Skip to content
This repository has been archived by the owner on May 21, 2021. It is now read-only.

Commit

Permalink
0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
kachick committed Apr 13, 2012
1 parent 2d630a1 commit de13b71
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 25 deletions.
6 changes: 6 additions & 0 deletions History.rdoc
@@ -1,3 +1,9 @@
=== 0.0.2 2012-04-14

* modify:
* .value -> .intern, .value_for
* #==, #eql?, #hash

=== 0.0.1 2012-04-13

* 1 major enhancement:
Expand Down
1 change: 1 addition & 0 deletions Manifest.txt
Expand Up @@ -7,3 +7,4 @@ lib/flyweight.rb
test/test_helper.rb
test/test_flyweight.rb
example/example.rb
example/benchmark.rb
8 changes: 4 additions & 4 deletions README.rdoc
Expand Up @@ -24,10 +24,10 @@ A tiny template for the "Flyweight Pattern"
end
end

a = Material.value :metal, 2000
b = Material.value :metal, 2000
c = Material.new :metal, 2000
d = Material.value :paper, 50
a = Material.intern :metal, 2000
b = Material.intern :metal, 2000
c = Material.new :metal, 2000
d = Material.intern :paper, 50
a == b #=> true
a.equal? b #=> true
a == c #=> true
Expand Down
75 changes: 75 additions & 0 deletions example/benchmark.rb
@@ -0,0 +1,75 @@
#!/usr/local/bin/ruby -w

$VERBOSE = true

require 'benchmark'
require_relative '../lib/flyweight'

class Material
include Flyweight

def initialize(looks, price, other=nil)
@looks, @price, @other = looks, price, other
end
end

class HeavyParts
DATA = 'str' * 10000000

def initialize
@content = DATA.dup
end
end

TIMES = 100000

Benchmark.bm do |bm|
bm.report 'Light Instant .new' do
TIMES.times do
Material.new :metal, 2000
end
end

bm.report 'Light Instant .intern' do
TIMES.times do
Material.intern :metal, 2000
end
end

bm.report 'Light Keep .new' do
TIMES.times.map do
Material.new :metal, 2000
end
end

bm.report 'Light Keep .intern' do
TIMES.times.map do
Material.intern :metal, 2000
end
end

bm.report 'Heavy Instant .new' do
TIMES.times do
Material.new :metal, 2000, HeavyParts.new
end
end

bm.report 'Heavy Instant .intern' do
TIMES.times do
Material.intern :metal, 2000, HeavyParts.new
end
end

bm.report 'Heavy Keep .new' do
TIMES.times.map do
Material.new :metal, 2000, HeavyParts.new
end
end

bm.report 'Heavy Keep .intern' do
TIMES.times.map do
Material.intern :metal, 2000, HeavyParts.new
end
end
end

6 changes: 3 additions & 3 deletions example/example.rb
Expand Up @@ -12,10 +12,10 @@ def initialize(looks, price)
end
end

a = Material.value :metal, 2000
b = Material.value :metal, 2000
a = Material.intern :metal, 2000
b = Material.intern :metal, 2000
c = Material.new :metal, 2000
d = Material.value :paper, 50
d = Material.intern :paper, 50
p a == b #=> true
p a.equal? b #=> true
p a == c #=> true
Expand Down
48 changes: 36 additions & 12 deletions lib/flyweight.rb
Expand Up @@ -23,14 +23,15 @@
# a == d #=> false
# a.equal? d #=> false
module Flyweight
VERSION = '0.0.1'.freeze

VERSION = '0.0.2'.freeze
POOL_NAME = :FLYWEIGHT_POOL

module Eigen
def value(*values)
pool = if singleton_class.const_defined? :FLYWEIGHT_POOL, false
singleton_class::FLYWEIGHT_POOL
def intern(*values)
pool = if singleton_class.const_defined? POOL_NAME, false
singleton_class.const_get POOL_NAME
else
singleton_class.const_set :FLYWEIGHT_POOL, {}
singleton_class.const_set POOL_NAME, {}
end

if pool.has_key? values
Expand All @@ -39,21 +40,44 @@ def value(*values)
pool[values] = new(*values)
end
end

alias_method :value_for, :intern

private

def inherited(klass)
klass.singleton_class.const_set POOL_NAME, {}
end
end

class << self
private

def included(mod)
raise ArgumentError unless mod.kind_of? ::Module

mod.extend Eigen
mod.module_eval do
extend Eigen
singleton_class.const_set POOL_NAME, {}
end
end
end

def ==(other)
sources_for = ->obj{
obj.instance_variables.map{|var|obj.instance_variable_get var}
}
def eql?(other)
self.class == other.class && (
sources_for = ->obj{
obj.instance_variables.map{|var|obj.instance_variable_get var}
}

sources_for[self] == sources_for[other]
sources_for[self].__send__ __callee__, sources_for[other]
)
end

alias_method :==, :eql?

def hash
instance_variables.inject(instance_variables.hash){|sum, var|
instance_variable_get(var).hash ^ sum
}
end
end
25 changes: 19 additions & 6 deletions test/test_flyweight.rb
Expand Up @@ -8,17 +8,22 @@ class Material
def initialize(looks, price)
@looks, @price = looks, price
end

def values
[@looks, @price]
end
end

class SubMaterial < Material
end

def test_normaly
a = Material.value :metal, 2000
b = Material.value :metal, 2000
c = Material.new :metal, 2000
d = Material.value :paper, 50
e = SubMaterial.value :metal, 2000
a = Material.intern :metal, 2000
b = Material.intern :metal, 2000
c = Material.new :metal, 2000
d = Material.intern :paper, 50
e = SubMaterial.intern :metal, 2000

assert_equal b, a
assert_same b, a
assert_equal c, a
Expand All @@ -27,8 +32,16 @@ def test_normaly
assert_same false, (d == a)
assert_same false, d.equal?(a)
assert_same false, d.__id__.equal?(a.__id__)
assert_equal e, a
assert_equal e.values, a.values
assert_same false, (e == a)
assert_same false, e.equal?(a)
assert_same false, e.__id__.equal?(a.__id__)

hash = {a => true}
assert_same true, hash[b]
assert_same true, hash[c]
assert_nil hash[d]
assert_nil hash[e]
end

end

0 comments on commit de13b71

Please sign in to comment.