Ruby元类混淆

我知道ruby中的所有类都是元类Class的实例。而“常规”对象就是这些类的实例(元类Class的实例)。


但是我一直在想,我的意思是类是对象的根,类本身是Class的实例(之所以称为Metaclass,是因为其实例是类)。我在一些博客中看到newClass 的method的一些重载。


因此,Class表现为类,但其实例是类。因此,似乎我们有一个圆圈,看起来类Class是其本身的实例。


我显然在这里漏了一点。类Class的起源是什么?


这是一个使我感到困惑的示例:


class Class

  def new

    #something

  end

end

但是关键字class暗示了Class类的一个实例。那么这是如何工作的呢?


叮当猫咪
浏览 584回答 3
3回答

翻翻过去那场雪

这项工作如何简单:并非如此。无论如何,不是在Ruby中。就像大多数其他语言一样,有些核心实体被假定为存在。它们从天上掉下来,在稀薄的空气中物化,神奇地出现。在Ruby中,其中一些神奇的东西是:Object没有父类,但是您不能定义没有父类的类,隐式直接父类始终为Object。[注意:可能有实现的定义的超类Object,但最终会有一个没有超类的类。Object是的实例Class,是的子类Object(这意味着间接Object是其Object本身的实例)Class是的子类Module,它是的实例ClassClass 是...的实例 Class这些事情在Ruby中都无法解释。BasicObject,Object,Module并且Class都需要在同一时间,因为他们有循环依赖于弹入的存在。仅仅因为这种关系无法用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的,和Class的class指针指向Class,我们就大功告成了。从系统外部很容易做到这一点,从内部看起来却很奇怪。但是,一旦它们确实存在,就完全有可能在纯Ruby中实现大多数行为。您只需要这些类的准系统版本,这要归功于Ruby的开放类,您可以在以后添加任何缺少的功能。在您的示例中,class Class没有创建名为的新类Class,而是重新打开了运行时环境提供给我们的现有类Class。因此,完全有可能解释Class#new纯Ruby中的默认行为:class Class  def new(*args, &block)    obj = allocate # another magic thing that cannot be explained in Ruby    obj.initialize(*args, &block)    return obj  endend[注意:实际上,它initialize是私有的,因此您需要使用obj.send(:initialize, *args, &block)来规避访问限制。]顺便说一句:这Class#allocate是另一种神奇的事物。它在Ruby的对象空间中分配了一个新的空对象,这在Ruby中是无法做到的。因此,Class#allocate运行时系统也必须提供某些东西。

阿波罗的战车

是的,Class是其自身的实例。它是Module的子类,也是类的实例,而Module是Object的子类,也是Object的实例。它确实是相当循环的-但这是核心语言的一部分,而不是库中的任何内容。当我们编写Ruby代码时,Ruby运行时本身没有相同的限制。不过,我从来没有听说过用“元类”这个词来谈论类。在Ruby中根本没有使用它,但是当它被使用时,它通常是正式称为“对象的单一类”的同义词,这是一个比Object-Module-Class三角形更令人困惑的主题。

杨魅力

“扭曲”链接给出了元圆度。它是从根的本征Class类到类的内置超类链接。这可以表示为BasicObject.singleton_class.superclass == Class了解该.class映射的一个线索是看到该映射是从本征类和超类链接派生的:对于一个对象x,x.class是本x征类的超类链中的第一个类。这可以表示为x.class == x.eigenclass.superclass(n)其中eigenclass的“概念别名” singleton_class (可抵抗带有立即值的问题),y.superclass(i)表示i-th的第超类,y并且n是的最小x.eigenclass.superclass(n)类。等效地,x.eigenclass将跳过的超类链中的本征类(请参见rb_class_real,这也表明在MRI中,甚至superclass链接都是间接实现的-它们是通过跳过“ iclasss ” 而产生的)。这导致class每个类别(以及每个本征类别)的始终是该Class类别。一种图象是通过提供该图。元类的混乱有两个主要来源:闲话。Smalltalk-80对象模型包含概念上的不一致性,这些不一致性已由Ruby对象模型纠正。此外,Smalltalk文献在术语中使用辩证法,不幸的是,在Ruby文献中尚未对此进行充分补救。元类的定义。目前,该定义指出元类是class的类。但是,对于所谓的“ 隐式元类 ”(在Ruby和Smalltalk-80的情况下),更合适的定义是类的元对象。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Ruby