30

It's probably not a paradox at all, but from a newbies perspective, it sure seems that way.

> Class.superclass
=> Module
> Class.superclass.class
=> Class
> Class.superclass.class.superclass
=> Module

So a class's parent is module, but module is a class?

How can I make sense of this?

Nathan
  • 7,627
  • 11
  • 46
  • 80
  • 2
    Possible duplicate of [The Class/Object Paradox confusion](http://stackoverflow.com/questions/7675774/the-class-object-paradox-confusion). See also [Ruby metaclass confusion](http://stackoverflow.com/questions/10525053/ruby-metaclass-confusion). – Andrew Marshall May 11 '12 at 21:19
  • 1
    These are great references. Thanks for pointing them out Andrew. – Nathan May 11 '12 at 23:01
  • Thank you for pointing out! – Alex Onozor Jul 13 '16 at 23:54

2 Answers2

78

TL;DR: Module is the superclass of Class. Module is an instance of Class.


Let me try to explain it more clearly. Please forgive my handwritten drawings - I don't have any fancy drawing software.

Every class in Ruby has 1 superclass*.

enter image description here

*Except for BasicObject, which doesn't have a superclass.

Read the above graphic like this: The superclass of Float is Numeric. The superclass of Numeric is Object, etc...

When you instantiate an object, the object will be an instance of some class. For example, "Nathan" is an instance of the String class. So is "Joe" or "John". 1 is an instance of the Fixnum class, as are 2, 3, 4, etc...

enter image description here

Read the above graphic like this: "Joe" is an instance of String. 1 is an instance of Fixnum, etc...

Well, in Ruby, unlike in most other languages, Class is a just another class, and it can be instantiated, too, just like Fixnum or String.

enter image description here

Read the above graphic like this: 0.01 is an instance of Float. String is an instance of Class, etc...

Realize that Fixnum is an instance of Class, just like "Nathan" is an instance of String. Just like "John" is an instance of String, Float is just an instance of Class. Every class is just an an instance of Class, even Class itself!

Whenever you write a new class in your app, you are just instantiating a new object whose class is Class, just like Hash.new instantiates a new Hash, or "Nathan" instantiates a new String.

# By running this, you will be instantiating a new Class, and 
# it will be named Post 
class Post < ActiveRecord::Base
end

# Here is another perfectly valid way to write the above code:
Post = Class.new(ActiveRecord::Base)

# you can even instantiate a Class without giving it an explicit name:
x = Class.new(ActiveRecord::Base)

# and since your new things are classes, they can be instantiated
obj1 = Post.new
obj2 = x.new

Furthermore, Module is just another instance of Class. Whenever you write a new module in your app, you are just instantiating a new Module.

# this will instantiate a new Module, and assign it to Foo
module Foo
end

# Here is another perfectly valid way to write the above code:
Foo = Module.new

# you can even instantiate a Module without giving it an explicit name.
m = Module.new

An aside: A Module is just a collection of methods and constants. Classes are also a collection of methods and constants, but with the added functionality of being able to be instantiated. A module cannot be instantiated. That is, m.new will not work.

So, referring back to the top graphic, your question can be answered directly:

So a class's parent is module, but module is a class?

You can see from the top graphic: Module is the superclass of Class.

From the bottom graphic: Module is an instance of Class.

John Douthat
  • 40,711
  • 10
  • 69
  • 66
  • Wow, very helpful. I switched the chosen answer to this one, though both of the answers you provided helped me. – Nathan May 12 '12 at 23:23
  • This topic deserves a full blown discussion, that has lots of tangents -- unfortunately Stack Overflow doesn't provide a good forum for that kind of thing. Ultimately though, my take-away from this is that there is some circular logic happening between Object and Class. From a laymen's perspective (I've been programming for all of ~5 months), my take on it is that since Ruby is implemented in C, that it is instantiated in C as well. And during this instantiation is where the circular logic gets declared. I hope I'm on the right track with that. – Nathan May 12 '12 at 23:28
  • 1
    @@Nathan You can see from the top graphic: Module is the superclass of Class.From the bottom graphic: Module is an instance of Class. **So that works in a circular way**. I guess that's important point – SamFlushing Aug 26 '13 at 13:12
  • 1
    when I create a class in Ruby by typing in class Foo and then end on the next line, when I execute Foo.superclass I see "Object" and not "Module". Why is this? According to the above graph, the superclass of Class is Module right? But I don't see that when I run the code. – Jwan622 Nov 06 '14 at 17:22
  • @Jwan622 When you create a class, its superclass is `Object` unless you specify a different one. So, `Foo`'s superclass is `Object`. Foo is an instance of `Class`, and the superclass of `Class` is `Module`. – John Douthat Nov 06 '14 at 20:41
15

In your second example Class.superclass.class, you're calling Module.class. Module refers to a class, the Module class.

AnyClass.superclass.class will return Class, except for BasicObject.superclass.class

The distinction between a class and an instance is important. BasicObject is a class. It is a class that extends nil, which is a fancy way of saying it has no superclass. It is the root of the tree. EVERYTHING is an object, which is another way of saying everything is an instance of some class.

String Example

"Nathan" is an object.
"Nathan" is an instance of the String class.
"Nathan" is not a class.
"Nathan" has no superclass, because "Nathan" is not a class.

String is an object.
String is an instance of the Class class.
String's superclass is Object.

Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

Fixnum example

1 is an object.
1 is an instance of the Fixnum class.
1 is not a class.
1 has no superclass, because it is not a class.

Fixnum is an object.
Fixnum is an instance of the Class class.
Fixnum's superclass is Integer.

Integer is an object.
Integer is an instance of the Class class
Integer's superclass is Numeric.

Numeric is an object.
Numeric is an instance of the Class class.
Numeric's superclass is Object.

# everything below here is in the above example.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

So, finally:

Class is an object.
Class is an instance of the Class class. # this is probably the most important part.
Class's superclass is Module # 2nd most important part

Module is an object
Module is an instance of the Class class. # 3rd
Module's superclass is Object # 4th

# everything below here is in the above examples.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

In table form:

enter image description here

And if you would like to verify that it's all true, you can just run it in Ruby

"Nathan".is_a?(BasicObject) # => true    "Nathan" is an object.
"Nathan".class #=> String                "Nathan" is an instance of the String class.
"Nathan".is_a?(Class) #=> false          "Nathan" is not a class.
"Nathan".superclass # NoMethodError      "Nathan" has no superclass, because "Nathan" is not a class.

String.is_a?(BasicObject) #=> true       String is an object.
String.class #=> Class                   String is an instance of the Class class.
String.superclass #=> Object             String's superclass is Object.

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.

And starting from Class:

Class.is_a?(BasicObject) #=> true        Class is an object.
Class.class #=> Class                    Class is an instance of the Class class. # this is probably the most important part.
Class.superclass #=> Module              Class's superclass is Module # 2nd most important part

Module.is_a?(BasicObject) #=> true       Module is an object
Module.class #=> Class                   Module is an instance of the Class class. # 3rd
Module.superclass #=> Object             Module's superclass is Object # 4th

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.
John Douthat
  • 40,711
  • 10
  • 69
  • 66
  • Maybe what's confusing me is that everyone keeps saying everything is an object, but when I do BasicObject.class it returns Class. So I'm confused about how to understand what a "class" is. If BasicObject's class is Class, then isn't everything really a class, rather than an object? – Nathan May 11 '12 at 21:29
  • Lol, this is starting to feel like philosophy 101, Aristotle's unmoved mover and all that. So if everything is an object (an instance of a class), then what about BasicObject? BasicObject.class => Class. Class.class => Class. Yet, when you go up the chain to nil, you get nil.class => NilClass, and NilClass.class => Class. So if everything is an object (an instance of a class), then what's the initial class that everything instantiates from -- and how does it come into existence? – Nathan May 11 '12 at 21:59
  • So with the exception of `nil` and your own custom objects, everything is an instance of the Class class -- including Class. Also, there's a class called Module, who's superclass is Object. Module is the superclass of Class. Which means that Object is the super-duper class of Class. Does that sound about right? If yes, then the only thing left is to ponder is how can Object be an instance of Class, yet Class (through Module) is a child of Object? – Nathan May 11 '12 at 22:49
  • BTW, thank you so much for your help and explanations. My brain always find recursions, inversions, and stuff like that to be a bit awkward. I suppose it comes easier for some -- but imagine everyone finds it a bit odd to think in those terms. Anyway, thanks again. – Nathan May 11 '12 at 22:58
  • All classes are objects, but not all objects are classes. No problem. I hope it helped you. Maybe someone can come along and make it clearer than I can. – John Douthat May 11 '12 at 23:09