Ruby Notes > Metaprogramming > Singleton Class

Singleton Class

Tags:  

What is a Singleton Class (or Metaclass)?

A Singleton Class is a hidden class that all objects in Ruby can have.  The Singleton Class is associated with a single object and not shared by all object of the same type/class.  Look at it this way, if we have two instances of strings:

  x = "string x"
y = "string y"

x and y both share the String class...

  x.class #=> String
y.class #=> String
x.class.equal? y.class #=> true

if we define a method on Kernel, we can gain a reference directly to the Singleton Class...

  # based on RCR231
module Kernel
unless Kernel.respond_to? :singleton_class
def singleton_class
class << self; self; end
end
end
end

x.singleton_class #=> #<Class:#<String:0x2c9deb4>>
y.singleton_class #=> #<Class:#<String:0x2c9c49c>>
x.singleton_class.equal? y.singleton_class #=> false

See how the Singleton Class is different for each object.

Note: In Ruby 1.9, the base/super class of the Singleton Class changed to Class instead of the class of the object.  see: http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l37 

How can you access the Singleton Class?

There is one idiom in Ruby:

  (class << obj; self; end)

Which may look strange, but what is happening is your are switching context to the obj's Singleton Class with "class << obj;"..."end".  Then within that context, you are returning "self" which references the Singleton Class inside that context.

RCR231 suggests the following Kernal method to make access easy:

  module Kernel
unless Kernel.respond_to? :singleton_class
def singleton_class
class << self; self; end
end
end
end

Outstanding Questions...

  1. What is the difference between "class Foo; def Foo.bar; 1; end; end" and "class Foo; class << self; def bar; 1; end; end; end"?  As far as I can find, they are exactly the same.
  2. Why doesn't "x.singleton_class.methods - Class.methods" return any methods?  It seems methods defined in the Singleton Class context magically appear on the object's method list (e.g. x.methods).

Links




                


 RSS of this page