Ruby Classes and Superclasses

An interesting question came up in this week’s Seven Languages in Seven Weeks skype call. We initially thought it might be a difference between versions of Ruby, but having looked more closely, i don’t think it is. Both 1.8.7 and 1.9.2 behave in this slightly odd way.

For reference, we are talking about Figure 2.1: Ruby Metamodel on page 26.

As we all now know, 4 is an object.

> 4.class
 => Fixnum

Fixnum inherits from Integer which inherits from Numeric.

> Fixnum.superclass
 => Integer
> Integer.superclass
 => Numeric

Each of Fixnum, Integer and Numeric are of class Class.

> [Fixnum, Integer, Numeric].map(&:class)
 => [Class, Class, Class]

The superclass of Numeric is Object.

> Numeric.superclass
 => Object

But the superclass of Class goes to Module and then to Object.

> Class.superclass
 => Module 
> Module.superclass
 => Object

And now, through the power of my very limited Open Office Drawing skills, i shall try to demonstrate what i think the diagram really looks like.

So where did Module come from? Why is a Class also a Module? And if Numeric is of class Class, why is its superclass not also Module?

I don’t think it’s particularly important to know these things, but they were interesting questions and i don’t know the answers.

Does anyone know?

8 comments on “Ruby Classes and Superclasses

  1. Ruby Metaprogramming book explains it all nicely :) It’s also easier, and the book (also prag meta videos) explain it as thinking about going one to the right to find the class, and then up the superclass chain.

    • Thanks, Stuart! I definitely think it helps to think of going horizontally for class and vertically for superclass.

      I’m still confused about why Class itself inherits from Module.

      • A class is just a module that can also be instantiated which is why Class is a subclass of Module. And everything is a subclass (eventually) of Object. Don’t worry about what exactly the Object class is — just remember that it’s Objects all the way down.

  2. I think this is Ruby’s “everything is an object” mentality coming out. Any given _object_ has a class (Numeric, Fixnum, etc.) but, of course, we can’t have the notion of a “class” without that too being an object. So the _objects_ Fixnum, Numeric, etc. have a class of Class. Class, the type, has its own (albeit short) class hierarchy via Module to Object.

    • I think you’re absolutely right. It’s just a bit weird, when you look closely, isn’t it!

  3. It gets even better. The class of Class is itself

    > Class.class
    => Class

    As well as … the class of Module

    > Module.class
    => Class

    Warning: I’m going to say some very obvious-sounding things on this post. It’s necessary to start slow because things get a bit tricky after a while.

    “X.superclass == Y” (red lines) is a different thing from “X.class == Y” (blue lines).

    Red lines are “class / subclass” relationships: they are generated by doing “class X x = Numeric.new
    => #

    When a class is subclassed, it gets inserted in the “ancestor list” of its subclass:

    > Fixnum.ancestors
    => [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]

    Fixnum.ancestors will be used by all Fixnum instances (1, 2, etc) in order to find their methods.

    Modules are different. They are inserted in the ancestor list (it’s a little more complicated than that, but we can assume that much) when they are *included* in a class:

    > module Foo end
    > Numeric.send :include, Foo
    > Fixnum.ancestors
    => [Fixnum, Integer, Numeric, Foo, Comparable, Object, Kernel, BasicObject]

    My Hunch is that Class “inherits” some of this “insert yourself into the ancestors list” functionality from Module. This must be why Class is a subclass of Module. I would have to look at the Ruby source code in order to be sure.

    Numeric is an instance of Class because it can be instantiated and subclassed. It is *not* as subclass of Class because its instances aren’t classes. Numbers are not used in the method lookup chain at all; that is why there is no line, red or blue. between Module and Numeric.

    If you are intrigued in Ruby’s Object model, I can only recommend the excellent “Metaprogramming Ruby” from Paolo Perrotta. I’ve used it as a reference while writing this.

    Paolo is also a great speaker; if you have the opportunity, I recommend you to come watch his presentation next month in Madrid (more info @ http://conferenciarails.org/ ).

    • Oh my gosh.

      *BOMF* the sound of my brain exploding!

      thank you so much for the detailed reply! :)

  4. I agree with Stuart. The Ruby Metaprogramming book is good at explaining it. Funny thing is that there they always go up and to the right, while you went to the left, but the idea is the same. Cool that you managed to reproduce it on your own.

    I sitll don’t have my head wrapped around it entirely, but I’ve gotten through most of the book and although I don’t think I could explain it yet, I do have a feel for it. It also gets really interesting when concept of the eigenclass is thrown into the diagram. That’s when I realize that it was starting to sink in.

Leave a reply to chris floess Cancel reply