0.0
No commit activity in last 3 years
No release in over 3 years
Multiton provides a transparent, thread safe and highly compatible implementation of the multiton (and singleton) patterns in pure Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.1.4
~> 1.1.0
~> 4.7.3
~> 0.5.5
~> 2.3.0
~> 3.8.0
~> 13.0.1
~> 6.2.1
~> 0.18.1
~> 1.6.0

Runtime

~> 0.1.3
 Project Readme

Multiton

Gem Version Build Status Inline docs

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  #=> 47143710911900
C.instance.object_id  #=> 47143710911900

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:0x00562e486384c8 @initialized_at=2017-04-17 20:00:15 +0000>

# Some time later...
Timestamp.instance.elapsed_seconds  #=> 542.955918039

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  #=> 47387777147320
C.instance(:one).object_id  #=> 47387777147320

C.instance(:two).object_id  #=> 47387776632880
C.instance(:two).object_id  #=> 47387776632880

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?  #=> false

Card.instance(5, :hearts).draw
Card.instance(10, :spades).draw

Card.instance(5, :hearts).drawn?    #=> true
Card.instance(10, :spades).drawn?   #=> true
Card.instance(2, :diamonds).drawn?  #=> false

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?  #=> false

serialized_card = Marshal.dump(Card.instance(2, :diamonds))

Marshal.load(serialized_card).drawn?  #=> false

Card.instance(2, :diamonds).draw

Marshal.load(serialized_card).drawn?  #=> true

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  #=> 47418482076880
F.instance.object_id  #=> 47418482076880

Note that C, D, E and F are all considered different classes and will consequently not share any instances.

Contributing

  1. Fork it ( https://github.com/gdeoliveira/ruby_multiton/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am "Add some feature")
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request