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?
TL;DR: Module is the superclass of Class. Module is an instance of Class.
Every class in Ruby has 1 superclass*.
*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...
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.
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With