如何做好这项工作
简单:它没有。无论如何,不在Ruby中。
就像在其他大多数语言中一样,有一些核心实体被简单地假设存在。它们从天而降,变得空气稀薄,奇迹般地出现。
在Ruby中,其中的一些神奇的事情是:
Object
没有一个超类,但你不能没有超定义一个类,隐含的直接超类总是Object
。 [注意:可能有实现定义的超类Object
,但最终会有一个没有超类的。]
Object
是Class
一个实例,这是Object
子类(这意味着间接Object
是Object
自身的实例)
Class
被的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
's和Class
的class
指针指向Class
,我们就大功告成了。
这很容易从系统外部做,它看起来很奇怪。
然而,他们一旦确实存在,那么完全可以在纯Ruby中实现其大部分行为。您只需要这些类的准系统版本,这要感谢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)
绕过访问限制]
作者:Class#allocate
是另一个那些神奇的东西。它在Ruby的对象空间中分配一个新的空对象,这是Ruby中无法做到的。因此,Class#allocate
也必须由运行时系统提供。
'Class.class#=> Class' – Flexoid
它一直都是乌龟! –
另请参见[类/对象悖论混乱](http://stackoverflow.com/questions/7675774/the-class-object-paradox-confusion)。 –