【问题标题】:Can someone explain the Class.superclass.class.superclass paradox?有人可以解释 Class.superclass.class.superclass 悖论吗?
【发布时间】:2012-05-20 11:19:38
【问题描述】:

这可能根本不是一个悖论,但从新手的角度来看,确实是这样。

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

所以一个类的父类是模块,但模块是一个类?

我该如何理解这一点?

【问题讨论】:

标签: ruby metaprogramming


【解决方案1】:

TL;DR:模块是类的超类。模块是一个类的实例。


让我试着更清楚地解释它。请原谅我的手写绘图 - 我没有任何精美的绘图软件。

Ruby 中的每个类都有 1 个超类*。

*BasicObject 除外,它没有超类。

像这样阅读上图:Float 的超类是 Numeric。 Numeric的超类是Object等……

当您实例化一个对象时,该对象将是某个类的实例。例如,“Nathan”是 String 类的一个实例。 “乔”或“约翰”也是如此。 1 是 Fixnum 类的一个实例,与 2、3、4 等一样......

像这样阅读上图:“Joe”是 String 的一个实例。 1 是 Fixnum 的一个实例,等等……

嗯,在 Ruby 中,与大多数其他语言不同,Class 只是另一个类,它也可以被实例化,就像 Fixnum 或 String 一样。

像这样阅读上图:0.01 是 Fl​​oat 的一个实例。 String 是 Class 的实例等...

意识到Fixnum是Class的一个实例,就像“Nathan”是String的一个实例一样。就像 "John" 是 String 的一个实例,Float 只是 Class 的一个实例。每个类都只是类的一个实例,甚至是类本身!

每当您在应用程序中编写新类时,您只是在实例化一个类为 Class 的新对象,就像 Hash.new 实例化一个新 Hash,或者“Nathan”实例化一个新 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

此外,Module 只是 Class 的另一个实例。每当您在应用中编写新模块时,您只是在实例化一个新模块。

# 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

顺便说一句:模块只是方法和常量的集合。类也是方法和常量的集合,但具有能够被实例化的附加功能。无法实例化模块。也就是说,m.new 将不起作用。

所以,回到上图,你的问题可以直接回答:

所以一个类的父类是模块,但模块是一个类?

从上图可以看出:模块是类的超类。

从下图中:模块是一个类的实例。

【讨论】:

  • 哇,很有帮助。尽管您提供的两个答案都对我有所帮助,但我将选择的答案切换为这个答案。
  • 这个话题值得全面讨论,它有很多切线——不幸的是,Stack Overflow 并没有为这类事情提供一个好的论坛。但最终,我从中得出的结论是在对象和类之间发生了一些循环逻辑。从外行的角度来看(我已经编程了大约 5 个月),我的看法是,因为 Ruby 是用 C 实现的,所以它也是用 C 实例化的。在这个实例化过程中,循环逻辑被声明。我希望我在正确的轨道上。
  • @@Nathan 从上图中可以看出:Module 是 Class 的超类。从下图中:Module 是 Class 的一个实例。 这样可以循环使用。我想这很重要
  • 当我通过键入类 Foo 在 Ruby 中创建一个类然后在下一行结束时,当我执行 Foo.superclass 时,我看到“对象”而不是“模块”。为什么是这样?根据上图,Class 的超类是 Module 对吧?但是当我运行代码时我没有看到。
  • @Jwan622 当你创建一个类时,它的超类是Object,除非你指定一个不同的。所以,Foo 的超类是Object。 Foo 是Class 的一个实例,Class 的超类是Module
【解决方案2】:

在您的第二个示例 Class.superclass.class 中,您调用的是 Module.class。 Module 指的是一个类,Module 类。

AnyClass.superclass.class 将返回 Class,BasicObject.superclass.class 除外

类和实例之间的区别很重要。 BasicObject 是一个类。它是一个扩展 nil 的类,这是一种说它没有超类的奇特方式。它是树的根。 EVERYTHING 是一个对象,这是说一切都是某个类的实例的另一种说法。

字符串示例

"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 示例

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.

所以,最后:

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.

表格形式:

如果你想验证这一切都是真的,你可以在 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.

从类开始:

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.

【讨论】:

  • 也许让我感到困惑的是,每个人都在说一切都是对象,但是当我执行 BasicObject.class 时,它返回 Class。所以我对如何理解“类”是什么感到困惑。如果 BasicObject 的类是 Class,那么不就是所有的东西都是类,而不是对象吗?
  • 大声笑,这开始感觉像是哲学 101,亚里士多德不动声色的推动者等等。因此,如果一切都是对象(类的实例),那么 BasicObject 呢? BasicObject.class=> 类。 Class.class=> 类。然而,当你上链到 nil 时,你会得到 nil.class=> NilClass 和 NilClass.class=> Class。因此,如果一切都是对象(类的实例),那么一切实例化的初始类是什么——它是如何存在的?
  • 因此,除了nil 和您自己的自定义对象之外,一切都是Class 类的实例——包括Class。此外,还有一个名为 Module 的类,它的超类是 Object。 Module 是 Class 的超类。这意味着 Object 是 Class 的超级骗子类。那个听起来是对的吗?如果是,那么剩下的唯一需要思考的是,Object怎么可能是Class的实例,而Class(通过Module)是Object的子对象?
  • 顺便说一句,非常感谢您的帮助和解释。我的大脑总是觉得递归、倒置和类似的东西有点尴尬。我想这对某些人来说更容易——但想象一下,每个人都觉得用这些术语来思考有点奇怪。无论如何,再次感谢。
  • 所有类都是对象,但并非所有对象都是类。没问题。我希望它对你有所帮助。也许有人可以比我更清楚。
猜你喜欢
  • 2022-01-12
  • 1970-01-01
  • 2012-05-29
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-03
  • 1970-01-01
相关资源
最近更新 更多