multiton 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/multiton.rb +133 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6f0e0b23975e5dce8fb8e385fa2879c8ee613333
4
+ data.tar.gz: ded761377d1760ed824b859c1dd263bd537c2da2
5
+ SHA512:
6
+ metadata.gz: 61f729a4af67b5f2d1c5f394a02355fdf55442d8f07c3c11335b114498f9c347a65e8d8463759c058ee0c226f07ba3d9146f11daba2b36cebaf26b2c798f2a1f
7
+ data.tar.gz: 3be1065d99e97adbeccbe76e114b319ab8b0ba6b83ec4a7b239f06d94f2639937cece8f4e40d89b6b32036556eb9bf9484b0d9e86ac9b67c933ae7624bb5fe05
@@ -0,0 +1,133 @@
1
+ require 'thread'
2
+
3
+ # The Multiton class extends Singleton Pattern to collection level
4
+ # The main purpose is to have a collection of sole instanses of a particular class
5
+ # Possible application: a cache mapped to some DB
6
+ #
7
+ # == Usage
8
+ #
9
+ # To use Multiton, include it in your class
10
+ # class Klass
11
+ # include Multiton
12
+ # # ...
13
+ # end
14
+ #
15
+ # A single instance identified by some <ID> is created upon the first call of Klass.create(<ID>)
16
+ # This ensures that there's only one instance of the Klass for a given <ID>
17
+ #
18
+ # a, b = Klass.create(:id), Klass.create(:id)
19
+ # a == b
20
+ # # => true
21
+ # a.id == b.id
22
+ # # => true
23
+ #
24
+ # Before the call to Klass.initialize, instance variable @id is assigned to <ID> obtained from Klass.create
25
+ # class Klass
26
+ # include Multiton
27
+ # attr_reader :ID
28
+ #
29
+ # def initialize
30
+ # @ID = @id
31
+ # end
32
+ # end
33
+ #
34
+ # a = Klass.create(:id)
35
+ # a.ID == a.id
36
+ # # => true
37
+ # a.ID == :id
38
+ # # => true
39
+ #
40
+ module Multiton
41
+ attr_reader :id
42
+
43
+ def clone
44
+ raise TypeError, "can't clone instance of singleton #{self.class}"
45
+ end
46
+
47
+ def dup
48
+ raise TypeError, "can't dup instance of singleton #{self.class}"
49
+ end
50
+
51
+ def _dump(depth = -1)
52
+ raise TypeError, "can't marshall instance of singleton #{self.class}"
53
+ end
54
+
55
+ class << self
56
+ def __init__(klass)
57
+ klass.instance_eval {
58
+ @multiton__instances__ = {}
59
+ @multiton__mutex__ = Mutex.new
60
+ }
61
+
62
+ def klass.new(id, *args, &blk)
63
+ o = allocate
64
+ o.instance_variable_set(:@id, id)
65
+ o.instance_eval{initialize(*args, &blk)}
66
+ o
67
+ end
68
+
69
+ def klass.inherited(sub)
70
+ super
71
+ Multiton.__init__(sub)
72
+ end
73
+
74
+ def klass.create(id, *args, &blk)
75
+ return @multiton__instances__[id] if @multiton__instances__[id]
76
+ @multiton__mutex__.synchronize {
77
+ return @multiton__instances__[id] if @multiton__instances__[id]
78
+ @multiton__instances__[id] = new(id, *args, &blk)
79
+ }
80
+ @multiton__instances__[id]
81
+ end
82
+
83
+ def klass.destroy(id)
84
+ @multiton__mutex__.synchronize {
85
+ return @multiton__instances__.delete id
86
+ }
87
+ end
88
+
89
+ def klass.has_key?(id)
90
+ @multiton__instances__.has_key? id
91
+ end
92
+
93
+ def klass.each(*args, &block)
94
+ __instances__ = nil
95
+ @multiton__mutex__.synchronize {
96
+ __instances__ = @multiton__instances__.clone
97
+ }
98
+ __instances__.each *args, &block
99
+ end
100
+
101
+ def klass.to_a
102
+ instances = []
103
+ each { |k, v| instances << v }
104
+ instances
105
+ end
106
+
107
+ def klass.[](id)
108
+ create id
109
+ end
110
+
111
+ klass
112
+ end
113
+
114
+ private
115
+
116
+ # extending an object with Multiton is a bad idea
117
+ undef_method :extend_object
118
+
119
+ def append_features(mod)
120
+ # help out people counting on transitive mixins
121
+ unless mod.instance_of?(Class)
122
+ raise TypeError, "Inclusion of the Multiton module in module #{mod}"
123
+ end
124
+ super
125
+ end
126
+
127
+ def included(klass)
128
+ super
129
+ Multiton.__init__(klass)
130
+ klass.private_class_method :new, :allocate, :inherited
131
+ end
132
+ end
133
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multiton
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dmytro Milinevskyy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: The multiton pattern expands on the singleton concept to manage a map
14
+ of named instances as key-value pairs.
15
+ email: milinevskyy@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/multiton.rb
21
+ homepage: https://github.com/niamster/multiton
22
+ licenses:
23
+ - Ruby License
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: The multiton pattern implementation
45
+ test_files: []