Why classes are confusing in Ruby
I wrote before about how
Class are confusing in Ruby. I think I know what’s so confusing about it now.
In most other OO languages there are two concepts, objects and classes. Objects are instances of classes, and classes can be subclasses of other classes. Basically, each object or class has what could be described as a pointer. An object has a pointer to its class, and a class has a pointer to it’s superclass. In Java, where every class inherits directly or indirectly from
Object, there is a clear line from each individual object to the
Object class, via the object’s class and its class’s superclasses. Let’s take Bob, an employee:
class superclass superclass bob -> Employee -> Person -> Object
There’s a clear line from
Object, via bob’s class, and his class’s superclasses.
In Ruby, there’s still this line, but because classes are objects as well, there’s an extra line. There isn’t one pointer – there are two. Each class has a class and it has a superclass. That’s how you get to the point where
Object is an
Class. Here’s some beautiful ascii art to illustrate:
Class -------> Module -------> Object ^ | Class --------> Module -------> Object | ^ | | Class -------> Module -------> Object ^ | Class --------> Module -------> Object | ^ | | Employee ------> Person -------> Object ^ | bob
Every vertical pointer describes an
instance_of relationship. Every horizontal pointer describes an
is_a relationship. I haven’t drawn all the
instance_of relationships of the classes, because if I did I’d be drawing an infinite tree of
Object nodes, and I don’t have time tonight to do that.
That’s what makes
Class so confusing in Ruby. In most other OO languages that use
Object as the overall base class, there is a straight line between an object and
Object (with multiple inheritance you can get diamonds, but it all gets back to the one
Object eventually). With Ruby, if you follow all the relationships you end up with an infinite tree.
Of course, this is only because I’m insisting on following all the
instance_of relationships. In most circumstances you can just forget that classes are objects, and only follow the
is_a relationships. The only
instance_of relationships that usually matter are between non-class objects and their classes. But if you follow the rabbit hole, you’ll find just how deep it goes …
I’ve now very much clarified my thinking on Ruby classes. See: Understanding the Ruby object model.