这怎么做
简单:它在Ruby中不起作用。
就像在大多数其他语言中一样,有一些核心实体被认为是已经存在的。它们从天而降,凭空出现,魔法般地出现。
在Ruby中,其中一些神奇事物包括:
Object
没有超类,但你不能定义没有超类的类,隐含的直接超类始终是Object
。(注意:可能有Object
的实现定义超类,但最终会有一个没有超类的超类。)
Object
是Class
的一个实例,Class
是Object
的子类(这意味着间接地Object
也是Object
的实例)。
Class
是Module
的子类,Module
是Class
的一个实例。
Class
是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
。
因此,在纯Ruby中完全可以解释Class#new
的
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
return obj
end
end
[注意: 实际上,initialize
是私有的,因此您需要使用 obj.send(:initialize, *args, &block)
来规避访问限制。]
另外,Class#allocate
是另一个神奇的东西。它在 Ruby 的对象空间中分配了一个新的空对象,这是在 Ruby 中无法做到的事情。因此,Class#allocate
也是运行时系统必须提供的东西。
Class.class # => Class
- Flexoid