module Singleton

Das Singleton-Modul implementiert das Singleton-Pattern.

Verwendung

Um Singleton zu verwenden, fügen Sie das Modul Ihrer Klasse hinzu.

class Klass
   include Singleton
   # ...
end

Dies stellt sicher, dass nur eine Instanz von Klass erstellt werden kann.

a,b = Klass.instance, Klass.instance

a == b
# => true

Klass.new
# => NoMethodError - new is private ...

Die Instanz wird beim ersten Aufruf von Klass.instance() erstellt.

class OtherKlass
  include Singleton
  # ...
end

ObjectSpace.each_object(OtherKlass){}
# => 0

OtherKlass.instance
ObjectSpace.each_object(OtherKlass){}
# => 1

Dieses Verhalten bleibt bei Vererbung und Klonen erhalten.

Implementierung

Dies wird erreicht durch

Singleton und Marshal

Standardmäßig gibt Singleton’s _dump(depth) einen leeren String zurück. Die Marshallisierung entfernt standardmäßig Zustandsinformationen wie Instanzvariablen aus der Instanz. Klassen, die Singleton verwenden, können benutzerdefinierte _load(str)- und _dump(depth)-Methoden bereitstellen, um einen Teil des vorherigen Zustands der Instanz beizubehalten.

require 'singleton'

class Example
  include Singleton
  attr_accessor :keep, :strip
  def _dump(depth)
    # this strips the @strip information from the instance
    Marshal.dump(@keep, depth)
  end

  def self._load(str)
    instance.keep = Marshal.load(str)
    instance
  end
end

a = Example.instance
a.keep = "keep this"
a.strip = "get rid of this"

stored_state = Marshal.dump(a)

a.keep = nil
a.strip = nil
b = Marshal.load(stored_state)
p a == b  #  => true
p a.keep  #  => "keep this"
p a.strip #  => nil