通常,对象的单例类的超类是该对象的类.即,对于具有单例类的任何对象foo
,以下条件成立:
foo.singleton_class.superclass == foo.class
然而,对于类来说,这可能有些无聊:每个类的类都是Class
,所以每个类的单例类的超类总是Class
.
这并不是特别有用,因为它会打破一些合理的假设.例如,如果我有这样的内容:
class Super
def self.super_singleton_method; end
end
class Sub < Super; end
我希望能拨打Sub.super_singleton_method
.然而,为了做到这一点,Super.singleton_class
需要位于Sub.singleton_class
的方法查找链中的某个位置.
因此,对于类,规则略有不同:类的单例类的超类就是该类的超类的单例类.即,对于任何类别Foo
,以下条件成立:
Foo.singleton_class.superclass == Foo.superclass.singleton_class
如果需要,您可以判断系统中的每个类是否都是这样:
ObjectSpace.each_object(Class).select do |klass|
klass.singleton_class.superclass != klass.superclass.singleton_class
end
#=> [BasicObject]
所以,如你所见,这个属性does代表all classes except 100.
为什么BasicObject
是不同的,简单的答案是BasicObject
没有超类,因此我们不能应用该规则.因此,对于所有符合以下条件的对象,我们都会采用更一般的规则
foo.singleton_class.superclass == foo.class
而BasicObject
的班级是Class
,因此,
BasicObject.singleton_class.superclass == BasicObject.class
BasicObject.singleton_class.superclass == Class
还有,为什么Ruby中没有其他对象将Class
类作为其超类?
从Class
继承的唯一原因是覆盖Ruby中继承或方法查找的行为.但Ruby不允许覆盖这一点.继承和方法查找的工作方式是语言规范的一部分,不能更改.因此,从Class
继承是非法的:
class MyClass < Class; end
# can't make subclass of Class (TypeError)
因此,不可能有任何对象具有Class
个超类、except个单例类类.(Ruby当然可以打破自己的规则,因为规则是由Ruby制定的.)
BasicObject的Singleton_Class超类背后的逻辑是如何在Ruby中实现的?
事实并非如此.您无法解释这在Ruby中是如何工作的,因为它是Ruby本身定义的一部分.
这类似于Class
是Module
的子类,但Module
是一个类,即Class
的实例.您不能使用Ruby的规则从Ruby内部解释这一点,但Ruby实现当然可以进行设置,以使其工作,因为Ruby实现本身不必遵守Ruby的规则:它是执行规则的人,所以它可以 Select 不为自己执行规则.