I m having trouble understanding the concept of eigenclass or singleton class in ruby. I read a lot that the eigenclass is a class's class. That doesn't make sense to me as for me a class's class is actually Class as all classes are actually instances of the class Class.
Another thing I don't quite get is the following statement: a class method is actually an instance method of the class eigenclass. The eigenclass is accessible this way :
YourClass = Class.new
class << YourClass
def class_method
end
end
But if the eigenclass is indeed the YourClass class (that is Class), shouldn't the preceding piece of code open the class Class and add to it the instance method class_method making it accessible to all of its future instances (that is any regular class defined in the future)?
I actually kind of feel that the singleton class is not the same as Class. When you do :
class MyClass
end
MyClass.singleton_class
you get #<Class:MyClass> which is different from the output of MyClass.class => Class
What is that #<Class:MyClass> output ? This has nothing to do with namespace as otherwise there would be two: Class::MyClass...
I'm Looking for a simple and unambiguous explanation of the eigenclass concept in order to clarify my ideas.
Singleton classes hold methods that are specific to a single object.
For generic objects, it's a nice-to-have feature. But for classes, it's crucial. Let's start with the objects:
Singleton classes for objects
Instance methods are usually defined in classes. All instances of the same class share the same instance methods. The singleton class sits between the object and its class. It allows each instance to have its own set of methods, independent of the other instances.
If we have two classes,
FooandBarwith 2 instances eacha,bandc,d:You would have this class structure: (simplified, excluding modules)
Ruby creates those singleton classes lazily, for example when calling
singleton_class.So when defining a method
a.hello, it is not stored ina's classFoo, but ina's singleton class:Because of that,
bdoesn't see that method, even though both areFooinstances:And we can even define a method with the same name for
bwithout interfering witha:We could also define a generic
helloinFooand override it on a per instance level: (you usually don't do that, but it's possible)Singleton classes for classes
The above is especially important for classes. Each class is an instance of
Class:Let's say we wanted to have a method
Foo.hello, where would we define it?Instance methods are usually defined in the instance's class, so we could define it in
Foo's class:But that would make the method available to all instances of
Class:It would be better to have a place that's exclusive to the
Fooinstance. And that place isFoo's singleton class:or
Just like
a.helloabove, this method is only available toFoo:We call these methods class methods, but they are really just instance methods of the singleton class:
And if you compare the singleton methods for classes with those for objects, you'll see that they are identical. That's because in Ruby, classes are objects too, and all objects work alike.