Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

ruby - Can someone explain the Class.superclass.class.superclass paradox?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...