module Multiton

The Multiton extension implements the multiton pattern in a manner similar to Ruby standard library's Singleton module. As a matter of fact Multiton can be used to implement the singleton pattern in a very straightforward way:

class C
  extend Multiton
end

C.instance.object_id  #=> 47362978769640
C.instance.object_id  #=> 47362978769640

In order to generate and access different instances a key must be provided as a parameter to the initialize method:

class C
  extend Multiton

  def initialize(key)
    # Initialize this instance (if needed).
  end
end

one = C.instance(:one)
two = C.instance(:two)

one.object_id               #=> 46941338337020
C.instance(:one).object_id  #=> 46941338337020

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

Almost any object or set of objects will work as a valid key. The key assembly is transparently handled by Multiton internally, leaving the end user with an uncluttered and familiar way of designing their classes:

class Person
  extend Multiton

  attr_reader :full_name

  def initialize(name:, surname:)
    self.full_name = "#{surname}, #{name} --- (id: #{object_id})".freeze
  end

  private

  attr_writer :full_name
end

alice = Person.instance(name: "Alice", surname: "Alcorta")
bob = Person.instance(name: "Bob", surname: "Berman")

alice.full_name                                               #=> "Alcorta, Alice --- (id: 46921440327980)"
Person.instance(name: "Alice", surname: "Alcorta").full_name  #=> "Alcorta, Alice --- (id: 46921440327980)"

bob.full_name                                                 #=> "Berman, Bob --- (id: 46921440022260)"
Person.instance(name: "Bob", surname: "Berman").full_name     #=> "Berman, Bob --- (id: 46921440022260)"

Note that even though keyword arguments will work with Multiton, passing the keywords in a different order will generate a different instance. It is left up to the end user to design their key in a way that minimizes the possibility of improper use.

Constants

VERSION

Current version of Multiton.

Public Instance Methods

_load(args_string) → an_instance click to toggle source

Creates or reconstitutes a multiton instance from args_string, which is a marshalled representation of the key argument(s) passed to instance.

Returns a multiton instance.

# File lib/multiton.rb, line 89
def _load(args_string)
  instance(*Marshal.load(args_string)) # rubocop:disable Security/MarshalLoad
end
dup → a_class click to toggle source

Creates a duplicate of the multiton class. Instances will not be shared between the original and duplicate classes.

Returns a new class.

Calls superclass method Multiton::Mixin#dup
# File lib/multiton.rb, line 100
def dup
  super.tap {|klass| klass.instance_variable_set(:@__multiton_instances, InstanceBox.new) }
end
instance(*args_key) → an_instance click to toggle source

Creates or retrieves the instance corresponding to args_key.

Returns a multiton instance.

# File lib/multiton.rb, line 111
def instance(*args_key)
  key = Marshal.dump(args_key)
  @__multiton_instances.get(key) || @__multiton_instances.store(key, new(*args_key))
end

Private Instance Methods

allocate → nil click to toggle source

Empty implementation of the allocate method to block the original implemented in Class. Effectively does nothing.

Returns nil.

# File lib/multiton.rb, line 126
def allocate; end
inherited(subclass) → nil click to toggle source

This is called when a multiton class is inherited to properly initialize subclass. Instances will not be shared between the superclass and its subclasses.

Returns nil.

Calls superclass method
# File lib/multiton.rb, line 136
def inherited(subclass)
  super
  subclass.instance_variable_set(:@__multiton_instances, InstanceBox.new)
  nil
end
initialize_copy(_source) → self click to toggle source

This is called (on the clone) when a multiton class (_source) is cloned to properly initialize it. Instances will not be shared between the original and cloned classes.

Returns self.

Calls superclass method
# File lib/multiton.rb, line 150
def initialize_copy(_source)
  super
  extend Multiton
  self
end
new(*args) → new_instance click to toggle source

Creates a new multiton instance and initializes it by passing args to its constructor.

Returns a new multiton instance.

Calls superclass method
# File lib/multiton.rb, line 163
def new(*args)
  super
end