红宝石元类的困惑红宝石元类的困惑(Ruby metaclass confusion)

2019-05-13 23:40发布

据我所知,在Ruby中所有的类都是元类类的实例。 和“正规”对象(元类类的实例),这些类的实例。

但是,我一直在想,我的意思是类对象的根类是自己的Class的实例(被称为元类,因为它的实例是类)。 我在一些博客看到方法的一些压倒一切的new Class类的。

因此类行为为一类,但它的实例是类。 如此看来,我们有一个圆圈,它看起来喜欢Class类是自己的一个实例。

我清楚地缺少点这里。 什么是类类的由来?

这里有一个交代不清的我举一个例子:

class Class
  def new
    #something
  end
end

但关键字class意味着Class类的一个实例。 那么,如何做好这项工作?

Answer 1:

如何做到这一点的工作

易:没有。 不是在Ruby中,反正。

就像在大多数其他语言,但是也有一些简单的假设存在着一些核心实体。 他们从天上掉下来,物化凭空,奇迹般地出现。

在Ruby中,其中的一些神奇的事情是:

  • Object没有一个父类,但不能定义一个无父类,隐含的直接超类总是Object 。 [注:有可能是实现定义的超类Object ,但最终,将有一个不具有一个超类。]
  • Object是的实例Class ,这是的一个子类Object (这意味着间接Object是实例Object本身)
  • Class是的子类Module ,这是一个实例Class
  • Class是实例Class

这一切都不可以用Ruby解释。

BasicObjectObjectModuleClass都需要在同一时间,因为它们具有循环依赖于弹入存在。

正因为这种关系不能在Ruby代码来表示,这并不意味着Ruby语言规范不能说它是如此。 它是由实现者想出一个办法做到这一点。 毕竟,Ruby实现访问,你作为一个程序员没有对象的水平。

例如,Ruby实现可以先创建BasicObject ,同时设置它的superclass的指针和它的class指针指向null

然后,它会创建Object ,设置它的superclass指针BasicObject及其class指针指向null

接着,它创建Module ,设置其superclass指针指向Object和它的class指针指向null

最后,它创建Class ,并设置其superclass指针指向Module和它的class指针指向null

现在,我们可以覆盖BasicObject的, Object的, Module的,以及Classclass指针指向Class ,我们就大功告成了。

这是很容易从系统外的事,它只是看起来从里面怪异。

一旦他们确实存在,但是,它是完全有可能实现最自己的行为以纯红宝石。 你只需要这些类的非常准系统版本,由于Ruby的公开课,可以在以后添加任何缺少的功能。

在您的例子中, class Class不创建一个名为新类Class ,它被重新打开现有的Class ,这是由运行时环境给我们。

所以,这是完全可能的解释的默认行为Class#new纯红宝石:

class Class
  def new(*args, &block)
    obj = allocate # another magic thing that cannot be explained in Ruby
    obj.initialize(*args, &block)
    return obj
  end
end

[注:实际上, initialize是私有的,所以你需要使用obj.send(:initialize, *args, &block) ,以规避访问限制]

BTW: Class#allocate是那些神奇的事情又一个。 它分配在Ruby的对象空间,这恐怕是不能用Ruby做一个新的空对象。 所以, Class#allocate是什么,必须由运行时系统,以及提供。



Answer 2:

是的,是类本身的实例。 它是模块的子类,这也是类的一个实例,和模块是对象的一个​​子类,这也是类的一个实例。 这的确是很圆 - 但这是核心语言,不是在图书馆的一部分。 Ruby运行时本身不具有thast你或我,当我们编写Ruby代码做同样的限制。

我从来没有听说过用来谈论类词“元类”,虽然。 它不是在Ruby中使用的威力,但是当它是,它通常是用于什么正式称为“单例类的对象,而”这是一个更加混乱的话题不是对象的模块级三角形的代名词。



Answer 3:

有由“扭”链接给出元圆。 这是从根本上的eigenclass到内置的超链接Class类。 这可以表示为

BasicObject.singleton_class.superclass == Class

甲线索理解.class地图是看到此映射从eigenclass和超链接导出:为对象xx.class是在超类链中的第一类x的eigenclass。 这可以表示为

x.class == x.eigenclass.superclass(n)

其中eigenclass是“概念上的别名”的singleton_class (耐与立即值的问题), y.superclass(i)表示i -TH的超类yn是最小的,使得x.eigenclass.superclass(n)是一类。 同样地,在超链eigenclasses x.eigenclass被跳过(见rb_class_real这也显示,在MRI,甚至superclass链接是间接实现的-它们跳过出现)。 这导致所述class的每个类的(以及每eigenclass的)是恒定的Class的类。

一种图象是通过提供该图 。

元类混乱有2个主要来源:

  • Smalltalk的 。 Smalltalk的-80的对象模型包含由所述Ruby对象模型整流概念不一致。 此外,Smalltalk的文献使用在术语辩证法,不幸的是还没有被充分地在Ruby文献补救。

  • 元类的定义 。 目前,定义指出 。 然而,对于所谓的“ ”(Ruby和Smalltalk-80的情况下)一个更恰当的定义将是类元对象 。



Answer 4:

虽然这是一个有点过时, 这篇文章_why可能有助于理解的行为。 你可以找到更深的下潜到保罗·佩罗塔的主题元编程红宝石 。



文章来源: Ruby metaclass confusion