Ruby元类混淆
我知道ruby中的所有类都是元类类的实例。“常规”对象是这些类的实例(元类的实例) 但我一直想知道,我的意思是类是对象的根,类本身就是类的实例(称为元类,因为它的实例是类)。我在一些博客中看到类的方法Ruby元类混淆,ruby,metaclass,Ruby,Metaclass,我知道ruby中的所有类都是元类类的实例。“常规”对象是这些类的实例(元类的实例) 但我一直想知道,我的意思是类是对象的根,类本身就是类的实例(称为元类,因为它的实例是类)。我在一些博客中看到类的方法new 所以类的行为就像一个类,但它的实例是类。看起来我们有一个圆圈,看起来类本身就是一个实例 我在这里显然漏掉了一点。阶级的起源是什么 下面是一个让我困惑的例子: class Class def new #something end end 但是关键字class意味着类的实例。那
new
所以类的行为就像一个类,但它的实例是类。看起来我们有一个圆圈,看起来类本身就是一个实例
我在这里显然漏掉了一点。阶级的起源是什么
下面是一个让我困惑的例子:
class Class
def new
#something
end
end
但是关键字
class
意味着类的实例。那么这是如何工作的呢?尽管它有点过时,但可能有助于理解这种行为。你可以在Paolo Perrotta的书中找到更深入的主题。是的,类本身就是一个实例。它是Module的一个子类,也是类的一个实例,Module是Object的一个子类,也是类的一个实例。它确实是非常循环的——但这是核心语言的一部分,而不是库中的东西。Ruby运行时本身没有编写Ruby代码时您或我所具有的限制
不过,我从未听说过“元类”这个词用来谈论课堂。它在Ruby中使用得并不多,但当它被使用时,它通常是官方称为“对象的单例类”的同义词,这是一个比对象模块类更令人困惑的话题
这是怎么工作的
很简单:它没有。无论如何,不是用Ruby
与大多数其他语言一样,有些核心实体被简单地假设为存在。它们从天而降,凭空而出,神奇地出现
在Ruby中,一些神奇的东西是:
没有超类,但不能定义没有超类的类,隐式直接超类始终是对象
。[注意:对象
,但最终会有一个没有超类的超类。]对象可能有实现定义的超类
是对象
的一个实例,该类是类
的一个子类(这意味着间接地对象
是对象
本身的一个实例)对象
是类
的子类,它是模块
类
是Class
Class
BasicObject
、Object
、Module
和Class
都需要同时出现,因为它们具有循环依赖关系
仅仅因为这种关系不能用Ruby代码表示,并不意味着Ruby语言规范不能说它必须如此。这取决于实现者找到一种实现方法。毕竟,Ruby实现具有作为程序员所不具备的对对象的访问级别
例如,Ruby实现可以首先创建BasicObject
,将其超类
指针和类
指针设置为null
然后,它创建对象
,将其超类
指针设置为基本对象
,将其类
指针设置为空
接下来,它创建模块
,将其超类
指针设置为对象
,将其类
指针设置为空
最后,它创建类
,将其超类
指针设置为模块
,将其类
指针设置为空
现在,我们可以覆盖基本对象
,对象
,模块
,和类
指针指向类
,我们就完成了
这在系统外很容易做到,只是从内部看起来很奇怪
然而,一旦它们确实存在,就完全有可能在纯Ruby中实现它们的大部分行为。您只需要这些类的基本版本,由于Ruby的开放类,您可以在以后添加任何缺少的功能
在您的示例中,类类
不是创建名为类
的新类,而是重新打开运行时环境提供给我们的现有类
因此,完全有可能在纯Ruby中解释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)
来规避访问限制。]
顺便说一句:
类#分配
是另一个神奇的东西。它在Ruby的对象空间中分配一个新的空对象,这是Ruby无法做到的。因此,类#分配
也必须由运行时系统提供。有一个由“twist”链接给出的元循环。它是从根的特征类到类
类的内置超类链接。这可以通过以下方式表示:
BasicObject.singleton_class.superclass == Class
x.class == x.eigenclass.superclass(n)
理解.class
映射的一条线索是将此映射视为从本征类和超类链接派生而来:对于对象x
,x.class
是x
本征类的超类链中的第一个类。这可以通过以下方式表示:
BasicObject.singleton_class.superclass == Class
x.class == x.eigenclass.superclass(n)
其中,eigenclass
是singleton\u类的“概念别名”
(抵抗立即值的问题),y.超类(i)
表示i
-th超类的y
,n
最小,因此x.本征类。超类(n)
是一个类。等价地,特征值