Type:
Module

The Singleton module implements the Singleton pattern.

Usage

To use Singleton, include the module in your class.

1
2
3
4
class Klass
   include Singleton
   # ...
end

This ensures that only one instance of Klass can be created.

1
2
3
4
5
6
7
a,b  = Klass.instance, Klass.instance
 
a == b
# => true
 
Klass.new
# => NoMethodError - new is private ...

The instance is created at upon the first call of Klass.instance().

1
2
3
4
5
6
7
8
9
10
11
class OtherKlass
  include Singleton
  # ...
end
 
ObjectSpace.each_object(OtherKlass){}
# => 0
 
OtherKlass.instance
ObjectSpace.each_object(OtherKlass){}
# => 1

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 and taint state, 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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"
a.taint
 
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
_dump
  • References/Ruby on Rails/Ruby/Classes/Singleton

_dump(depth = -1) Instance Public methods By default, do not retain any state

2025-01-10 15:47:30
dup
  • References/Ruby on Rails/Ruby/Classes/Singleton

dup() Instance Public methods Raises a

2025-01-10 15:47:30
_load
  • References/Ruby on Rails/Ruby/Classes/Singleton

_load Class Public methods By default calls instance(). Override to retain singleton

2025-01-10 15:47:30
clone
  • References/Ruby on Rails/Ruby/Classes/Singleton

clone() Instance Public methods Raises a

2025-01-10 15:47:30