Ruby中BasicObject的单例类父类为Class类的原因及实现逻辑
Ruby中BasicObject单例类父类的特殊逻辑解释
首先明确一个常规规则:一个对象的单例类会继承该对象父类的单例类。但Ruby里的根类BasicObject是个例外,我们先看实际代码运行结果:
查看BasicObject本身的父类:
>> BasicObject.superclass => nil
但查看它的单例类的父类时,结果却指向Class:
>> BasicObject.singleton_class.superclass => Class
为什么其他对象的父类都不是Class?
不管是普通实例对象还是普通类对象,它们的父类都遵循常规继承链:
- 普通实例对象(比如字符串
"hello")的父类是它的所属类String,String的父类是Object,最终到BasicObject; - 普通类对象(比如
String)的父类是它的超类Object,而非Class——Class是所有类的元类(类的类),类对象本身是Class的实例,但父类关系和实例所属类是两个不同的概念。
BasicObject单例类父类设为Class的背后逻辑
Ruby的方法查找机制依赖完整的继承链,BasicObject作为继承链的顶端没有父类,那它的单例类如果也没有父类,就会导致BasicObject的类方法(比如allocate、new)找不到来源——因为这些类方法本质是定义在Class或Module中的。
把BasicObject的单例类父类设为Class,就能补全这条类方法的查找链:当调用BasicObject的类方法时,若在自身单例类找不到,就会去Class中查找,确保所有类的根对象也能正常使用通用类方法,同时让整个单例类继承链形成合理闭环。
内容的提问来源于stack exchange,提问作者srira
相关产品推荐
相关产品推荐

