module Singleton - Documentation for Ruby 4.0 (original) (raw)
The Singleton module implements the Singleton pattern.
Usage
To use Singleton, include the module in your class.
class Klass include Singleton
end
This ensures that only one instance of Klass can be created.
a,b = Klass.instance, Klass.instance
a == b
Klass.new
The instance is created at upon the first call of Klass.instance().
class OtherKlass include Singleton
end
ObjectSpace.each_object(OtherKlass){}
OtherKlass.instance ObjectSpace.each_object(OtherKlass){}
This behavior is preserved under inheritance and cloning.
Implementation
This above is achieved by:
- Making Klass.new and Klass.allocate private.
- Overriding Klass.inherited(sub_klass) and Klass.clone() to ensure that the Singleton properties are kept when inherited and cloned.
- Providing the Klass.instance() method that returns the same object each time it is called.
- Overriding Klass._load(str) to call Klass.instance().
- Overriding Klass#clone and Klass#dup to raise TypeErrors to prevent cloning or duping.
Singleton and Marshal
By default Singleton’s _dump(depth) returns the empty string. Marshalling by default will strip state information, e.g. instance variables from the instance. Classes using Singleton can provide custom _load(str) and _dump(depth) methods to retain some of the previous state of the instance.
require 'singleton'
class Example include Singleton attr_accessor :keep, :strip def _dump(depth)
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
p a.keep
p a.strip