Module: Multiton

Extended by:
Extensible
Defined in:
lib/multiton.rb,
lib/multiton/mixin.rb,
lib/multiton/utils.rb,
lib/multiton/version.rb,
lib/multiton/instance_box.rb

Overview

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.

Defined Under Namespace

Modules: Mixin, Utils Classes: InstanceBox

Constant Summary collapse

VERSION =

Current version of Multiton.

"0.1.1".freeze

Instance Method Summary collapse

Instance Method Details

#_load(args_string) ⇒ Object

call-seq:

_load(args_string) => an_instance

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.



89
90
91
# File 'lib/multiton.rb', line 89

def _load(args_string)
  instance(*Marshal.load(args_string)) # rubocop:disable Security/MarshalLoad
end

#dupObject

call-seq:

dup => a_class

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

Returns a new class.



100
101
102
# File 'lib/multiton.rb', line 100

def dup
  super.tap {|klass| klass.instance_variable_set(:@__multiton_instances, InstanceBox.new) }
end

#instance(*args_key) ⇒ Object

call-seq:

instance(*args_key) => an_instance

Creates or retrieves the instance corresponding to args_key.

Returns a multiton instance.



111
112
113
114
# 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