Class or Singleton Methods in Ruby
A deep dive into the Singleton methods and the Singleton Classes.
Table of contents:
↦ Definition of Singleton methods
↦ Why called as Singleton methods?
Definition of Singelton Methods
Those methods that live on a classes’ singleton class, are known as singleton methods.
Before understanding what singleton class is, lets first get a look at how class methods are created:
To declare a class method, there are 2 ways:
self.method_name
class_name.method_name
Since class variables cannot be accessed as method through class or class object, we set a class method and instance method to access it.
You cannot access class method through class instance or instance method through class itself.
A class method can also be called as a singleton method.
Why?
Because these methods live on an object called singleton class, which lives invisibly between the class Test
and class Class
.
Need Proof? Check this out:
p Test.is_a? singleton_class
# => false
We check if the class Test
is singleton class or not and it isn’t a singleton class, it's just a class
which is an instance of a class Class
.
p Test.class_methods
# => undefined method `class_methods' for Test:Class (NoMethodError)
In the program, we already defined a class method, class_count
, but Ruby doesn’t provide this method to be excessed as class methods.
Instead, to access class methods, we need to give the following method:
p Test.singleton_methods
# => [:class_count]
Earlier we said that all class methods or singleton methods live on singleton class. So let's access it:
p Test.singleton_class
# => #<Class:Test>
Singleton class, Class:Test
, lives between the class Test
and class Class
. Now when we check the instance methods of a singleton class, Class:Test
, we get the following:
p Test.singleton_class.instance_methods(false)
# => [:class_count]
So, we can conclude that the singleton methods, class_count
, live inside a singleton class, Class:Test
. In other words, the class_count
method is an instance method of singleton class Class:Test
.
There’s no such thing as a Ruby class method, only instance methods that look and smell like class methods. — Jem Zornow
p Test.class_count
# => 2
When class Test
is created, a singleton class, Class:Test
, is created on the fly that contains the method class_count
. When we make the above call by passing a singleton method to class Test, this invokes class Test, accesses method from Class:Test
and outputs the result.
But Why Singleton Class?
Instance methods are defined inside a class Test
or any other class as defined in a program. So class methods would have to be created on parent (one upper level) of class Test
which is class Class
. Assuming Ruby created class methods on the class Class
, then that method would be available to any classes and not just class Test
because all classes descend from class Class. And with this, we could easily override the function of built-in class methods or override our class methods with similar names.
So to summarize: Class methods aren’t methods that are defined at the class level but are defined on the implicitly-created singleton class, that’s built at the moment when class is created in the system.
Definition of Singleton Class:
Singleton Class is where the singleton methods live. These are classes that are invisible and created automatically by Ruby after declaring any new class. Singleton classes or Eigenclass or Metaclasses are all same with different names.
p Test.singleton_class.ancestors
# => [#<Class:Test>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Another way to create class or singleton methods is by…
Instance Eval:
Instance eval is a class/singleton method that enables us to explicitly create class or singleton methods outside the scope of the class.
You can access these methods as you normally would access if they were defined inside the scope of the class.
Accessing a Singleton Class
We don’t create but access the Class C
‘s singleton class, Class:C
with the shovel operator, <<
.
This enables us to declare a singleton method just like an instance method.
If we had to define a class method, Klass_method
, to Class C
we would declare it as self.Klass_method
. But in Singleton Class, we declare it as an instance because the methods of singleton class are singleton methods of Class C
.
Accessing Singleton methods
Just as Singleton classes are implicitly created when we declare a class, a singleton class of a class object is also created when the class is instantiated. At line #10 we can see a singleton class of a class object c
of Class C
.
When we access singleton methods of class C
, we see there are no methods which mean the Klass_method
was added to the singleton class of a class object c
of a class C
and not the class C
itself!
Another way to declare a singleton method on the class object: