multiton 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []