The singleton class is an often discussed topic among Rubyists, especially new ones who are gradually learning about Ruby's metaprogramming features. There are a number of blog posts or articles already about this... I'll just add one more.
This is my take on the Singleton class, presented in the way I typically explain it to new Ruby enthusiasts.
Firstly, I'll assume that you know that (almost) everything is an object in Ruby, and that includes classes.
Next, we need to know that objects can have behavior of their own that are not shared with other similar objects.
class MyClass def blah 'blah' end end obj = MyClass.new obj.hi # => NoMethodError def obj.hi 'hi' end obj.hi # => 'hi' another_obj = MyClass.new another_obj.hi # => NoMethodError obj.class # => MyClass another_obj.class # => MyClass
The above code shows one way to add instance-specific behavior. Interesting thing to note is that the new method is invokable only from the instance it was defined on and not from other instances of the same class. This means that the method was not added to the class of the instance.
Does that mean that an object itself can hold method definitions?
Well, the answer is no (unless it's an object that represents a class or a module). One of the reasons the concept of classes exists in Ruby is that they are meant to hold method definitions and act as blueprints for their instances, ie, they determine what methods can be invoked on their instances.
So where did the method hi go?
Yes, that's correct, it went into the singleton class of the instance. This hidden class is different from the class the instance was created from and is a Ruby implementation detail that is typically not revealed to anyone (there is only one way to get to the singleton class, which we'll talk about in a while). This is the reason it is sometimes called ghost class or anonymous class or shadow class. Some people also refer to it as metaclass but since it's not always a "class for a class" (but is more like a class for an object), this term is misleading. Another popular name is eigen class (which means "own class" in German).
The singleton class is created for an object as soon as the Ruby interpreter needs to add instance-specific behavior for that object (but not before that). Going forward, if more methods need to be added to the same object, its already-created singleton class is used. Also, more instances cannot be created using a particular singleton class (its new method raises an error). Because of this one-to-one relationship between an object and its singleton class, the word 'singleton' is used (I think).
So, what is the way in which one can get access to an object's singleton class?
# ... in continuation from previous snippet obj_singleton_class = class << obj; self; end obj_singleton_class.ancestors # => [MyClass, Object, Kernel] MyClass.ancestors # => [MyClass, Object, Kernel]
Here class << obj; self; end is the key: anything written after class << obj and before the corresponding end is evaluated against the context of the singleton class of obj, ie, self points to the singleton class.
In the above snippet, we return self, getting a reference to it in the variable obj_singleton_class. We then see that the singleton class fakes the same ancestry as the original class of the object. This implies that when a method is invoked on an object, Ruby first looks for the method definition in the object's singleton class (if it exists), if not, Ruby then continues looking up the normal inheritance hierarchy.
# ... in continuation from previous snippet obj.hi # method looked for in singleton class; found; invoked obj.blah # method looked for in singleton class; not found; looked for in MyClass; found; invoked obj.xyz # method looked for in singleton class, MyClass, Object, Kernel; not found; obj.method_missing() called, raising NoMethodError
Now hopefully we have understood how singleton classes work.
Let's quickly look at two other ways in which we could have added instance-specific behavior to an object:
class << obj def hi 'hi' end end
obj.instance_eval do def hi 'hi' end end
The former one should be clear from what has already been explained. The latter is tied to how def works with instance_eval (I'll probably cover this in another blog post).
Now, before concluding, let's take a step back and see if we've seen the syntax discussed so far, before. You'll probably recognize their use in defining class-level methods:
class MyClass def MyClass.my_class_method1 'class method 1' end def self.my_class_method2 'class method 2' end class << self def my_class_method3 'class method 3' end end end
And yes, you've guessed right: all class methods go into the singleton class of the object representing the class, in this case, the object referenced by the constant name: MyClass (remember classes are also objects). After all, these class method definitions need to go somewhere, and in such a way that the methods don't become part of the class's instances (ie, they aren't instance methods) nor do the methods go to the super class.
This particular usage of singleton classes can be called as metaclass but according to what we've discussed, they don't seem to have anything different from normal singleton classes. That said, there is a difference, about which you can read more here: Metaclass in Ruby
Singleton classes are fun! Enjoy exploring the uses of it!
(For more details, I recommend reading fellow-TWer Patrick Farley's Ruby internals blog series.)