Ruby Ruby 类的问题

uestc_bird · 2016年07月15日 · 最后由 uestc_bird 回复于 2016年07月22日 · 3071 次阅读

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 这些语言,有很多的资料可以去了解他们,不仅解释了现象,也解释了现象背后的原因,概念清晰,顺理成章。

推荐你看下 Ruby 元编程, Class 和 Module 很多东西非常像; 没有你所说的咬尾巴问题

#1 楼 @yingce 就是看了元编程才有那么多疑惑。能具体说一下这本书的那一节解释了这个问题? 面向对象的语言很多,但是从没有遇到过像 ruby 这样概念模糊的语言,难怪作者自己都说,这门语言的内部非常复杂。。。。。 当然,这很可能是思维被传统面向对象语言固化的原因。 但是搞不清这些基本概念,会很难受的。。。。。

语言就是这么设计的,javascript 里面 Function 也是这么设计的。 Object.prototype.toString.call(Function) 同样也会得到 [object Function]

rails toturial 里面的 ruby 章节提到过 ruby 的 class 与 superclass

#2 楼 @uestc_bird 我到时觉得我学习 Ruby 后才理解对象概念 也面向对象更彻底的语言

@derekyxie 看下他推荐的解释

或许 ruby 对实例、类的定义与其他语言有些区别,其他语言实例跟类是泾渭分明的,但在 ruby ,所有的类都是 Class 的实例,包括 Class 本身,而所有的类都最终继承自 BasicObject(除了 BasicObject 本身)。

用其他语言的逻辑去理解会混乱的,所以我干脆把实例和类当作两个互不相干的维度。 PS. 我觉得要理解这一切最终只能看源码了

#6 楼 @jude 我也是这样想的,估计 ruby 里面有些概念用传统的 OO 思想理解是不对的

实现的问题只能在 c 源码中得到解释. 要理解这个实现上的技术问题, 只能看源码. 源码包中的 class.c 应该能找到答案.

问题的重点是在: 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 类实例对象也是如此)进行了重载, 在重载中赋予了两种身份, 一个是类, 另一个是对象, 两种身份的实现互不干预.

#9 楼 @pinewong 有道理,说得通,不过要想知道底层机制,估计只有去看源码了。

#10 楼 @uestc_bird 我觉得你如果真的看了《Ruby 元编程》,并且看懂了的话,就不会提这种问题。

里面说的非常清楚,在 Ruby 里面,类也是实例,是 Class 类的实例,在 Java 也是一样,不知道有什么好困惑的。

你的问题用层层递进的三段式就可以回答: 1)Ruby 中一切都是对象(object),对象都是类(class)的实例 2)依据第一条,既然一切都是对象(object),那么类(class)同样也是对象,它们都是 Class 的实例 3)依据第二条,既然类也是对象,那么 Class 也必须是对象,它是 Class 的实例 请注意classClass的大小写不同

你唯一困惑的大概是 Class 是 Class 的实例,这个叫 “自指”,Java 里面也常用,典型的单例模式:

Class MyClass {
  private static MyClass myClass;
  public static MyClass getInstance() {
    if(null == myClass){
      myClass = new MyClass();
    }
    return myClass;
  }
}

在这段代码中,MyClass 暂时还不存在,怎么能在自身的代码中生成自己呢?其实就是一个占位功能来自指而已,编译器怎么实现是它自己的事情,你能理解就好了,还用得着看源代码深究?

如果对 Ruby 元编程其他内容没看懂的,建议看我的另一篇帖子:分析 Ruby 代码的执行环境

把他全部看成对象就好了啊

#11 楼 @sefier 你的帖子写得不错

String,Module,Class 都是类的名字,所以它们都是 Class 类。这是在下愚见。

如果用 JS 的机制,是很好理解的。。。 子类跟实例,并不冲突啊

[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 来表示)

#17 楼 @jude 这本书早闻大名,正准备开始看,非常好的建议,谢谢!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册