Since all methods are implemented and stored by the class definition, it should be impossible for an object to define its own methods. However, Ruby provides a way around this - you can define methods that are available only for a specific object. Such methods are called Singleton Methods. Let us look at an example of a singleton method:
The respond_to?
method tells us whether the object can respond to the given message. Apparently, no new instances of Foo
can respond to shout
- only the object to which this method was added to can. Thus it appears that the object foo
holds the method shout
all by itself.
Here the object foo
has the singleton method shout
. This is a singleton method because it belongs to just one instance of a class and will not be shared with others.
However, singleton methods contradict what we found early: instance objects cannot hold methods, only class definitions (objects of class Class
) can. It happens that the truth is somewhere in-between.
When you declare a singleton method on an object, Ruby automatically creates a class to hold just that method. This class is called the 'metaclass' of the object. All subsequent singleton methods of this object goes to its metaclass. Whenever you send a message to the object, it first looks to see whether the method exists in its metaclass. If it is not there, it gets propagated to the actual class of the object and if it is not found there, the message traverses the inheritance hierarchy.
In summary:
- Objects in Ruby only store the state. Its behaviour comes from its class definition.
- Objects can also have methods that are independent of the parent class definition. They are called singleton methods and are stored on the metaclass of the object. The metaclass is typically invisible to the programmer.
It is possible to access the metaclass of an object through a neat trick:
Lets first focus on the a
object. As you can see, we've added a singleton method shout
to it. This method is verified to exist as an instance method in a
's metaclass.
Now let look at how the metaclass
method is implemented. The class << self
syntax changes the current self
to point to the metaclass of the current object. Since we are already inside an instance method, this would be the instance's metaclass. The method simply returns self
which at this point is the metaclass of the instance.
A metaclass is almost a class in many respects. It however can't be instantiated:
The metaclass
method approach to inspect metaclasses in Ruby was popularized by _why through his metaid.rb.
Ruby 1.9 introduced the singleton_class
as a shorthand for the class << self
syntax we saw earlier. From now on, you can just call the singleton_class
instead of our custom metaclass
method.
In Ruby, both 'metaclass' and 'singleton class' means the same. You'll find them being used interchangeably in Ruby literature.
Metaclasses are the underlying mechanism using which Ruby provides us an object model with inheritance and mixins. However, you would rarely find this concept being used while writing Ruby code. . This is because Ruby ensures that the abstraction doesn't leak and effectively hides the semantics of metaclasses from the programmer. Even though this is the case, understanding metaclasses well helps in understanding Ruby's object model better.