Multiton
Multiton is an implementation of the multiton pattern in pure Ruby. Some its features include:
Installation
Add this line to your application's Gemfile:
gem "ruby_multiton"
And then execute:
$ bundle
Or install it yourself as:
$ gem install ruby_multiton
Usage
Implementing a singleton class
The easiest use case for Multiton is to implement a singleton class. To achieve this Multiton mimics the approach used
by the Singleton module from Ruby's standard library:
require "multiton"
class C
extend Multiton
end
C.instance.object_id
C.instance.object_id
As an example lets create a singleton object that returns the amount of seconds elapsed since it was first initialized:
class Timestamp
extend Multiton
def initialize
self.initialized_at = Time.now
end
def elapsed_seconds
Time.now - initialized_at
end
private
attr_accessor :initialized_at
end
Timestamp.instance
Timestamp.instance.elapsed_seconds
Implementing a multiton class
To implement a multiton class we will need a key
to be able to access the different instances afterwards. Multiton
achieves this by using the parameters passed to the initialize
method as the key
:
require "multiton"
class C
extend Multiton
def initialize(key)
end
end
C.instance(:one).object_id
C.instance(:one).object_id
C.instance(:two).object_id
C.instance(:two).object_id
As an example lets create multiton objects representing playing cards that we can check if they were drawn or not:
class Card
extend Multiton
def initialize(number, suit)
self.has_been_drawn = false
end
def draw
self.has_been_drawn = true
end
def drawn?
has_been_drawn
end
private
attr_accessor :has_been_drawn
end
Card.instance(10, :spades).drawn?
Card.instance(5, :hearts).draw
Card.instance(10, :spades).draw
Card.instance(5, :hearts).drawn?
Card.instance(10, :spades).drawn?
Card.instance(2, :diamonds).drawn?
Serializing and deserializing multiton instances
Multiton instances can be serialized and deserialized like regular objects. Continuing with the previous Card
example:
Card.instance(2, :diamonds).drawn?
serialized_card = Marshal.dump(Card.instance(2, :diamonds))
Marshal.load(serialized_card).drawn?
Card.instance(2, :diamonds).draw
Marshal.load(serialized_card).drawn?
Clonning, duplicating and inheriting from multiton classes
Multiton supports cloning, duplicating and inheriting from a multiton class:
require "multiton"
class C
extend Multiton
end
D = C.clone
E = D.dup
class F < E
end
F.instance.object_id
F.instance.object_id
Note that C
, D
, E
and F
are all considered different classes and will consequently not share any instances.
Contributing
- Fork it ( https://github.com/gdeoliveira/ruby_multiton/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am "Add some feature"
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request