As an object-oriented programming lanuage, everything in Ruby is an object. Everything. Once you learn how to make classes and create your own objects, it’s pretty easy to get the hang of this. However, there’s one object that is quite confusing to a Rubyist newb (like me) because it’s hidden: the singleton class, also know as the ghost class, metaclass, and eigenclass.
You can create objects by creating classes. The behavior of objects or instances of these classes can be defined by the methods within its class and superclasses (and modules mixed into them).
class Animal def speak puts "growl" end end dog = Animal.new dog.speak #=> growl
When a method is sent to an object, Ruby looks for the method in this order:
(1) Modules mixed into its Class –> (2) Class –> (3) Modules Mixed-in to Superclass –> (3) Superclass –> etc.
Singleton Classes & Methods
Singleton methods are methods that belong to a single object, a single instance of a class, and they are stored in its singleton class. You can define methods on individual objects like this:
def dog.speak puts "bark" end dog.speak #=> bark
Even though one is hidden, every object actually has two classes–its class and its singleton class. These methods that are dedicated to just one instance of an object are stored in that object’s singleton class.
These classes are automatically created when you create an object, but you have to open them up to define methods or modules on them. You can define a method on a singleton class in two ways:
dog = Animal.new def dog.speak puts "bark" end
dog = Animal.new class << dog def speak puts "bark" end end
Singleton Methods on Classes
The most common use of singleton methods is on class objects themselves. Classes are in fact objects so they also have two classes–a singleton class and a superclass. Defining methods on classes directly allows you to do things like keep track of instances of classes. You can see a full explanation of singleton classes of class here.
Here’s an example of a singleton method defined on a class:
class Animal def self.color puts "brown" end def dog.speak puts "bark" end end
When a method is sent to an object, Ruby actually looks for the method in this order:
(1) Modules mixed into the Singleon Class –> (2) Singleton Class –> (3) Modules mixed into its Class –> (4) Class –> (5) Modules Mixed-in to Superclass –> (6) Superclass –> etc.
Singleton classes might be confusing as first. But when you accept that every object has two classes rather than just one it’s a lot easier to understand.