This repository has been archived by the owner on May 21, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flyweight.rb
92 lines (75 loc) · 1.73 KB
/
flyweight.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# flyweight
# A tiny template for the "Flyweight Pattern"
# Copyright (C) 2012 Kenichi Kamiya
# @example
# class Material
# include Flyweight
#
# def initialize(looks, price)
# @looks, @price = looks, price
# end
# end
#
# 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
# a.equal? c #=> false
# a == d #=> false
# a.equal? d #=> false
module Flyweight
VERSION = '0.0.3'.freeze
POOL_NAME = :FLYWEIGHT_POOL
module Eigen
def intern(*values)
if (pool = _pool).has_key? values
pool[values]
else
pool[values] = new(*values)
end
end
alias_method :value_for, :intern
def flush
Flyweight.flush_pool! self
end
private
def inherited(klass)
Flyweight.prepare_pool! klass
end
def _pool
if singleton_class.const_defined? POOL_NAME, false
singleton_class.const_get POOL_NAME
else
Flyweight.prepare_pool! self
end
end
end
class << self
def prepare_pool!(mod)
mod.singleton_class.const_set POOL_NAME, {}
end
def flush_pool!(mod)
mod.singleton_class.const_get(POOL_NAME).clear
end
private
def included(mod)
mod.extend Eigen
prepare_pool! mod
end
end
def eql?(other)
self.class == other.class &&
_comparable.__send__(__callee__, other._comparable)
end
alias_method :==, :eql?
def hash
_comparable.inject(0){|sum, val|val.hash ^ sum}
end
protected
def _comparable
instance_variables.map{|var|instance_variable_get var}
end
end