How to create your own Singleton from Scratch

One of the 23 described patterns by the Gang of Four is the Singleton Pattern, which says only one object of a particular class is ever created and all further references to objects of the singleton class refer to the same underlying instance.

As you may know, Ruby provides you a singleton module that you can include in your class, and magically your class is a singleton out of the box.

But let’s say for the sake of learning you want to create your own Singleton from scratch.

All the work done by the Ruby Singleton module is:

  • creates the class variable
  • initializes it with the singleton instance
  • creates the class level instance method
  • makes the new method private
  • prevents your class to be a Eager class
class MySingleton

  # This would cause a eager instantiation,
  # something that we want to avoid
  # @@instance =

  def self.instance
    # this will prevent you to have a eager class
    @@instance ||= new

  # and finally the `new` method becomes private
  private_class_method :new

An equivalent implementation of MySingleton would be, using the Ruby library:

require 'singleton'

class RubySingleton
  include Singleton

We can demonstrate this by running both implementation through the same test suite

require 'spec_helper'
require 'singleton/my_singleton'
require 'singleton/ruby_singleton'

shared_examples "a singleton" do
  it 'should not be a eager class' do
    # will return 1 if is a eager class and 0 if not
    ObjectSpace.each_object(described_class){}.should == 0

  it 'should raise an error when calling the new method' do
    # `new` method is a private method
    expect {
    }.to raise_error

  it 'should always output the same instance' do
    singleton_instance = described_class.instance
    described_class.instance.should eql(singleton_instance)
    described_class.instance.class.should eql(singleton_instance.class)

describe MySingleton do
  it_behaves_like "a singleton"

describe RubySingleton do
  it_behaves_like "a singleton"

You can learn more about ObjectSpace.

Happy coding!

photo of David Silva

comments powered by Disqus