One of the most mysterious aspects of the Ruby object model is the existence of singleton classes. Maybe you also read about metaclasses or eigenclasses, they are actually all referring to the same thing. Still, the "official" name being singleton classes, I will use this term through this post.
You actually don't need to understand much of singleton classes (or to even know them at all) to write decent Ruby code. Though, as they form an essential part of the Ruby object model, it is an interesting knowledge to have.
The method dispatch problem
First, to fully understand the purpose of such classes, we have to look to another essential piece of Ruby: method dispatching. Consider the following code:
class Vehicle def initialize(kms) @kms = kms end def drive puts "let's go!" end end car = Vehicle.new(20_000) car.drive
Nothing fancy here. We define a class Vehicle with a method
drive and then create a new instance of it. Let’s dig into what these few lines of code actually do behind the scenes.
Internally, here is how Ruby is representing the class
Vehicle and its instance
car in memory:
car object is represented by Ruby using a C struct, holding the list of its instance variables and a pointer
klass to the its class. The class
Vehicle itself holds its list of methods in and a
super attribute pointing at its superclass (in our case,
Object, the default superclass for all classes).
As we can see, the
car object has actually no idea that it has a method named
drive. All it knows is that it owns an instance variable named
kms. When we call the method
drive on the object, Ruby will actually follow the
klass pointer of the underlying C struct to find the object's class. In the method list of this class, it will find the method
drive and then call it on the current value of
self, which is
As classes are also objects in Ruby, a similar strategy is used to resolve a method called on a class. Let's go back to the previous example and add some code:
class Vehicle @@registry =  def self.register(vehicle) @@registry << vehicle end # ... end car = Vehicle.new(20_000) Vehicle.register(car)
We just defined the class method
register on our
Vehicle class to manage a simple list of registered vehicles. Good. As we said, method dispatch works in the exact same way for classes than for objects. That means, calling
Vehicle.register should work as we saw before, but with the
Vehicle class instead of its instance.
Here is a schema similar to the one we saw earlier, showing the
So, our class
Vehicle owns an instance variable
registry and its
klass pointer is referencing the class of all classes,
Class (which defines the class method
new for example).
But then, where is the class method
register? It can't be into the method list
Vehicle. As we saw before, due to the way the Ruby object model works, it can only contains instance methods.
So, since method dispatch must work the same as for all other objects, Ruby should follow the
klass pointer of
Vehicle to find the method. However, this would mean that the
register method is defined as a method of
Class, which would mean all of our classes would get this method. So, neither of these solutions can work.
Ruby solves this problem using singleton classes.
Discovering singleton classes
A singleton class of an object (or a class) is a class created by Ruby only for this specific object. This class is somehow "hidden" to us, but it is there. When calling a method on this object, Ruby will look first into its singleton class, if there is one, to find that method.
For the rest of this post, we will refer to the singleton class of a class
#A (and to the one of an object
#a). So, taking back our example of the
Vehicle class, here is how things look when we define the
register class method:
The schema above is actually slightly simplified, as we will see in a few minutes. But for now let's focus of what is happening here. Writing
def self.register, we actually tell Ruby to open the singleton class of
self (which is then pointing to the
Vehicle class) and define the
register method on it.
Now, when we call
Vehicle.register, Ruby will look first into
#Vehicle instead of
Class, to find the
register method, calling it with the value of
self being the class
Vehicle. Since the
#Vehicle is pointing to
Class, Ruby can still follow the chain to find any other class method like
new. We are back on our feet.
Singleton classes can be defined in the exact same way for "regular" objects. We could then define a method only on a specific
car = Vehicle.new(20_000) def car.start puts "starting..." end
We open the singleton class of
car and define a
start method on it. This method is then only available for this specific object. Again, we can draw a similar schema showing the relation between
car, its singleton class and the
Move along, no class here
Remember when we said that singleton classes where hidden to us. For example, calling
class on the object will not return its singleton class
#car as we could expect, but its class
Vehicle. That is because internally, Ruby uses a special flag on the singleton class. Also, it cannot be instantiated like a regular class.
However, as the
super attribute of
#car is pointing to the original class
Vehicle, it is possible to override methods defined by
car = Vehicle.new(1000) bus = Vehicle.new(3000) def car.drive print "I'm driving a car! " super end car.drive # "I'm driving a car! let's go!" bus.drive # "let's go!"
We can have access to the singleton class by calling the
singleton_class method on the
car object. By inspecting the singleton class, we can see Ruby names it using the following pattern:
> car.inspect => "#<Vehicle:0x007fd4442c38f8>" > car.singleton_class.inspect => "#<Class:#<Vehicle:0x007fd4442c38f8>>"
This is also true for the singleton class of a class:
> Vehicle.inspect => "Vehicle" > Vehicle.singleton_class.inspect => "#<Class:Vehicle>"
The truth about Singleton Classes of Classes
So far, we learned that the class method
register is actually defined on the singleton class of
#Vehicle. But now let's take a slightly more complicated example:
class Vehicle @@registry =  def self.register(vehicle) @@registry << vehicle end end class Car < Vehicle def self.register(car) # register car plate super end end some_car = Car.new Car.register(some_car)
We created the class
Car which is a subclass of
Vehicle. We define as well a class method
Car that does some car-specific work and calls the
register method on the parent class
super. If we take the time to draw again a schema using what we know, here how it looks:
There is something that we miss here. The
Car class has a class method
register on its singleton class
#Car that clearly calls the
register method of its superclass,
Vehicle. But we saw that this method is itself defined on
#Vehicle have no relationship, how can Ruby get back on his feet to find the
register method of the superclass?
That's where the magic of the Ruby object model reveals itself. Here is the ultimate schema where we can see what are the real relationships between all the elements we looked at so far:
Take some time to analyze and understand this one, because for sure, it can be quite complicated and weird to get the first time. What happens is that, for the singleton class
#Car to be able to call the superclass's method
register defined on the singleton class
#Vehicle, Ruby actually make the
super pointer of
#Car points to
#Vehicle instead of class. That's why we are able to call a superclass class method from a subclass class method. In the end, even the
klass pointer of the
Object class points to
#Object (that's why can also define class methods on the
super pointer goes back to
Class. So, as all Ruby classes inherit from
Object, all of their singleton classes inherits from
#Object and ultimately from
From these last learnings, we can infer two rules that are part of the core principles of the entire Ruby object model:
The superclass of the singleton class of an object is the object’s class.
The superclass of the singleton class of a class is the singleton class of the class’s superclass.
Yep. Read it again a second time and a third time, just in case.
There are other ways to define methods on the singleton class of an object. We can use the special
class << syntax to directly open the singleton class and define methods on it:
car = Vehicle.new(2000) class << car def start "starting..." end end
Again, this is also true for classes, so you can also use this syntax to define class methods (you can see it a lot in some frameworks and libraries like Rails):
class Vehicle class << self def register(vehicle) @@vehicles << vehicle end end end
Another way of defining methods on the singleton class is to use a module and the
extend method. You may have already used
extend. What it actually does is opening the singleton class of the receiver object and add methods from the module passed in argument.