String.class #=> Class, String 是 Class 类的一个实例; Module.class #=> Class, Module 是 Class 类的一个实例; Class.class #=> Class,Class 是 Class 类的一个实例????
现象一: Class.superclass #=> Module 释义:Class 类的父类是 Module,既,Class 继承于 Module,或者说 Class 类是 Module 类的子类
现象二: Module.class #=> Class 释义:Module 类是 Class 类的一个实例
鸡生蛋,蛋生鸡问题?一条蟒蛇咬住了自己的尾巴?请指教
补充一点吧:我很想弄清楚这其中的机制,就是 how it works?有没有什么书或者资料可以推荐学习一下的(研究源码除外),元编程只是说了现象,没有解释原因。 像 C++、python 这些语言,有很多的资料可以去了解他们,不仅解释了现象,也解释了现象背后的原因,概念清晰,顺理成章。
语言就是这么设计的,javascript 里面 Function 也是这么设计的。 Object.prototype.toString.call(Function) 同样也会得到 [object Function]
rails toturial 里面的 ruby 章节提到过 ruby 的 class 与 superclass
或许 ruby 对实例、类的定义与其他语言有些区别,其他语言实例跟类是泾渭分明的,但在 ruby,所有的类都是 Class 的实例,包括 Class 本身,而所有的类都最终继承自 BasicObject(除了 BasicObject 本身)。
用其他语言的逻辑去理解会混乱的,所以我干脆把实例和类当作两个互不相干的维度。 PS. 我觉得要理解这一切最终只能看源码了
问题的重点是在:Ruby 中 Class 类的实例(如:Class, String, Module, Array)是一些特殊的对象,他们也能称作类
正常情况下类的实例都只是单纯的对象,Ruby 因为上述特殊的定义变得复杂,但我们能这么理解上述现象: 现象一:Class.superclass #=> Module 释义:Class 类的父类是 Module, 既,Class 类继承于 Module 类,或者说 Class 类是 Module 类的子类,这里 Module 的概念是类
现象二:Module.class #=> Class 释义:Module 类是 Class 类的一个实例,这里的 Module 实际上是对象的角度,应该理解成:Module 对象是 Class 类的一个实例
总结就是:这两个现象不能说明咬尾巴,因为上述问题实际上解释是:Module 对象.class.superclass == Module 类
至于源码这种复杂特殊关系的实现,我不清楚。但我猜想是将 Module(其他上述提到特殊的 Class 类实例对象也是如此)进行了重载,在重载中赋予了两种身份,一个是类,另一个是对象,两种身份的实现互不干预。
#10 楼 @uestc_bird 我觉得你如果真的看了《Ruby 元编程》,并且看懂了的话,就不会提这种问题。
里面说的非常清楚,在 Ruby 里面,类也是实例,是 Class 类的实例,在 Java 也是一样,不知道有什么好困惑的。
你的问题用层层递进的三段式就可以回答: 1)Ruby 中一切都是对象(object),对象都是类(class)的实例 2)依据第一条,既然一切都是对象(object),那么类(class)同样也是对象,它们都是 Class 的实例 3)依据第二条,既然类也是对象,那么 Class 也必须是对象,它是 Class 的实例 请注意class和Class的大小写不同
你唯一困惑的大概是 Class 是 Class 的实例,这个叫“自指”,Java 里面也常用,典型的单例模式:
Class MyClass {
private static MyClass myClass;
public static MyClass getInstance() {
if(null == myClass){
myClass = new MyClass();
}
return myClass;
}
}
在这段代码中,MyClass 暂时还不存在,怎么能在自身的代码中生成自己呢?其实就是一个占位功能来自指而已,编译器怎么实现是它自己的事情,你能理解就好了,还用得着看源代码深究?
如果对 Ruby 元编程其他内容没看懂的,建议看我的另一篇帖子:分析 Ruby 代码的执行环境
[15] pry(main)> $ 1.class
From: object.c (C Method):
Owner: Kernel
Visibility: public
Number of lines: 5
VALUE
rb_obj_class(VALUE obj)
{
return rb_class_real(CLASS_OF(obj));
}
VALUE
rb_class_real(VALUE cl)
{
while (cl &&
((RBASIC(cl)->flags & FL_SINGLETON) || BUILTIN_TYPE(cl) == T_ICLASS)) {
cl = RCLASS_SUPER(cl);
}
return cl;
}
#7 楼 @uestc_bird 有一本书可以解答你的问题《ruby-under-a-microscope》,你可以看第三章。
简单地讲,ruby 用两种数据结构分别表示对象和类,RObject 表示对象,RClass 表示类,RObject 中有一个 klass 指针指向它的类,RClass 中既有一个 klass 指针指向它的类,也有一个 superclass 指针指向它的超类(这个超类也是用 RClass 来表示)