Ruby LanguageSingleton Class

Syntax

  • singleton_class = class << object; self end

Remarks

Singleton classes only have one instance: their corresponding object. This can be verified by querying Ruby's ObjectSpace:

instances = ObjectSpace.each_object object.singleton_class

instances.count            # => 1
instances.include? object  # => true

Using <, they can also be verified to be subclasses of the object's actual class:

object.singleton_class < object.class  # => true

References:

Introduction

Ruby has three types of objects:

  • Classes and modules which are instances of class Class or class Module.
  • Instances of classes.
  • Singleton Classes.

Each object has a class which contains its methods:

class Example
end

object = Example.new

object.class  # => Example
Example.class # => Class
Class.class   # => Class

Objects themselves can't contain methods, only their class can. But with singleton classes, it is possible to add methods to any object including other singleton classes.

def object.foo
  :foo
end
object.foo #=> :foo

foo is defined on singleton class of object. Other Example instances can not reply to foo.

Ruby creates singleton classes on demand. Accessing them or adding methods to them forces Ruby to create them.

Accessing Singleton Class

There are two ways to get singleton class of an object

  • singleton_class method.
  • Reopening singleton class of an object and returning self.
object.singleton_class

singleton_class = class << object
  self
end

Accessing Instance/Class Variables in Singleton Classes

Singleton classes share their instance/class variables with their object.

class Example
  @@foo = :example
end

def Example.foo
  class_variable_get :@@foo
end

Example.foo #=> :example

class Example
  def initialize
    @foo = 1
  end

  def foo
    @foo
  end
end

e = Example.new

e.instance_eval <<-BLOCK
  def self.increase_foo
    @foo += 1
  end
BLOCK

e.increase_foo
e.foo #=> 2

Blocks close around their instance/class variables target. Accessing instance or class variables using a block in class_eval or instance_eval isn't possible. Passing a string to class_eval or using class_variable_get works around the problem.

class Foo
  @@foo = :foo
end

class Example
  @@foo = :example 

  Foo.define_singleton_method :foo do
    @@foo
  end
end

Foo.foo #=> :example

Inheritance of Singleton Class

Subclassing also Subclasses Singleton Class

class Example
end

Example.singleton_class #=> #<Class:Example>

def Example.foo
  :example
end

class SubExample < Example
end

SubExample.foo #=> :example

SubExample.singleton_class.superclass #=> #<Class:Example>

Extending or Including a Module does not Extend Singleton Class

module ExampleModule
end

def ExampleModule.foo
  :foo
end

class Example
  extend ExampleModule
  include ExampleModule
end

Example.foo #=> NoMethodError: undefined method

Message Propagation with Singleton Class

Instances never contain a method they only carry data. However we can define a singleton class for any object including an instance of a class.

When a message is passed to an object (method is called) Ruby first checks if a singleton class is defined for that object and if it can reply to that message otherwise Ruby checks instance's class' ancestors chain and walks up on that.

class Example
  def foo
    :example
  end
end

Example.new.foo #=> :example

module PrependedModule
  def foo
    :prepend
  end
end

class Example
  prepend PrependedModule
end

Example.ancestors #=> [Prepended, Example, Object, Kernel, BasicObject]
e = Example.new
e.foo #=> :prepended

def e.foo
  :singleton
end

e.foo #=> :singleton

Reopening (monkey patching) Singleton Classes

There are three ways to reopen a Singleton Class

  • Using class_eval on a singleton class.
  • Using class << block.
  • Using def to define a method on the object's singleton class directly
class Example
end

Example.singleton_class.class_eval do
  def foo
    :foo
  end
end

Example.foo #=> :foo

class Example
end

class << Example
  def bar
    :bar
  end
end

Example.bar #=> :bar

class Example
end

def Example.baz
  :baz
end

Example.baz #=> :baz

Every object has a singleton class which you can access

class Example
end
ex1 = Example.new
def ex1.foobar
  :foobar
end
ex1.foobar #=> :foobar

ex2 = Example.new
ex2.foobar #=> NoMethodError

Singleton classes

All objects are instances of a class. However, that is not the whole truth. In Ruby, every object also has a somewhat hidden singleton class.

This is what allows methods to be defined on individual objects. The singleton class sits between the object itself and its actual class, so all methods defined on it are available for that object, and that object only.

object = Object.new

def object.exclusive_method
  'Only this object will respond to this method'
end

object.exclusive_method
# => "Only this object will respond to this method"

Object.new.exclusive_method rescue $!
# => #<NoMethodError: undefined method `exclusive_method' for #<Object:0xa17b77c>>

The example above could have been written using define_singleton_method:

object.define_singleton_method :exclusive_method do
  "The method is actually defined in the object's singleton class"
end

Which is the same as defining the method on object's singleton_class:

# send is used because define_method is private
object.singleton_class.send :define_method, :exclusive_method do
  "Now we're defining an instance method directly on the singleton class"
end

Before the existence of singleton_class as part of Ruby's core API, singleton classes were known as metaclasses and could be accessed via the following idiom:

class << object
  self  # refers to object's singleton_class
end