根据定义,对象的单例类也继承了对象超类的单例类,ruby中的BasicObject没有超类,因为它是最基本的类
BasicObject
>> BasicObject.superclass => nil
但是当同一个方法调用它的单例类时,结果是:
>> BasicObject.singleton_class.superclass => Class
还有为什么Ruby中没有其他对象将Class类作为超类?BasicObject的singleton_class的超类背后的逻辑是如何在Ruby中实现的?
Class
1hdlvixo1#
一般来说,对象的单例类的超类就是对象的类,也就是说,对于任何一个有单例类的对象foo,下面的公式成立:
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,以下成立:
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]
因此,正如您所看到的,这个属性 * 确实 * 适用于 * 除BasicObject * 之外的所有类。BasicObject不同的原因很简单,因为BasicObject没有超类,因此我们不能应用这个规则。
而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作为其超类,* 除了 * 类的单例类(Ruby当然可以打破自己的规则,因为它是制定规则的人)。BasicObject的singleton_class的超类背后的逻辑是如何在Ruby中实现的?你无法解释这在Ruby中是如何工作的,因为这是Ruby本身定义的一部分。这类似于Class是Module的子类,但是Module是一个类,也就是Class的一个示例,你不能用Ruby的规则来解释这一点,但是Ruby的实现当然可以设置一些东西来使它工作,因为Ruby的实现本身不必遵守Ruby的规则:它是执行规则的一方,因此它可以选择不为自己执行规则。
Module
drkbr07n2#
根据定义,对象的单例类也继承了对象超类的单例类。我们不要想当然地认为这是理所当然的,让我们弄清楚为什么要以这种方式实现它。在Ruby中,有示例方法和类方法,而类方法实际上是单例类的示例方法:
class MyClass def foo end def self.bar end end MyClass.instance_methods(false) #=> [:foo] MyClass.singleton_class.instance_methods(false) #=> [:bar]
如图所示:
MyClass ---> #<Class:MyClass> foo bar
现在,如果你创建一个子类MySubClass,它会从超类MyClass继承示例方法和类方法:
MySubClass
MyClass
class MySubClass < MyClass end MySubClass.instance_methods #=> [:foo, ...] MySubClass.singleton_class.instance_methods #=> [:bar, ...]
为了让它工作,必须为类和单例类都建立继承:
MyClass ---> #<Class:MyClass> foo bar ^ ^ | | MySubClass ---> #<Class:MySubClass>
Ruby在内部对此进行了优化--单例类只在需要的时候创建,但从概念上讲,这就是发生的事情。除此之外,MyClass和MySubClass已经带有一些内置的类方法,最著名的是用于创建示例的.new,还有.superclass。你可能知道.new的默认实现是在幕后调用.allocate的,所以在某个地方一定有一个包含这些方法的“根类”,因为它们是类方法,所以它必须位于单例类的顶部:
.new
.superclass
.allocate
<singleton root class> new allocate superclass ^ | ... | MyClass ---> #<Class:MyClass> foo bar ^ ^ | | MySubClass ---> #<Class:MySubClass>
这个神秘的顶级单例根类为所有其他类提供了基本的类方法,它是... Class!
Class.instance_methods(false) #=> [:allocate, :superclass, :subclasses, :new]
2条答案
按热度按时间1hdlvixo1#
一般来说,对象的单例类的超类就是对象的类,也就是说,对于任何一个有单例类的对象
foo
,下面的公式成立:然而,对于类来说,这会有些无聊:每个类的类都是
Class
,所以每个类的单例类的超类总是Class
。这不是特别有用,因为它会打破一些合理的假设,例如,如果我有这样的东西:
我希望能够调用
Sub.super_singleton_method
,但是,为了做到这一点,Super.singleton_class
需要位于Sub.singleton_class
的方法查找链中的某个位置。因此,对于类,规则有些不同:类的单例类的超类是该类的超类的单例类,即对于任何类
Foo
,以下成立:如果需要,可以检查系统中的每个类是否都是这样:
因此,正如您所看到的,这个属性 * 确实 * 适用于 * 除
BasicObject
* 之外的所有类。BasicObject
不同的原因很简单,因为BasicObject
没有超类,因此我们不能应用这个规则。而
BasicObject
的类是Class
,因此,还有为什么Ruby中没有其他对象将
Class
类作为超类?从
Class
继承的唯一原因是为了覆盖Ruby中继承和方法查找的工作方式,但是Ruby不允许覆盖这一点。继承和方法查找的工作方式是语言规范的一部分,不能更改。因此,从Class
继承是非法的:因此,不可能有任何对象以
Class
作为其超类,* 除了 * 类的单例类(Ruby当然可以打破自己的规则,因为它是制定规则的人)。BasicObject的singleton_class的超类背后的逻辑是如何在Ruby中实现的?
你无法解释这在Ruby中是如何工作的,因为这是Ruby本身定义的一部分。
这类似于
Class
是Module
的子类,但是Module
是一个类,也就是Class
的一个示例,你不能用Ruby的规则来解释这一点,但是Ruby的实现当然可以设置一些东西来使它工作,因为Ruby的实现本身不必遵守Ruby的规则:它是执行规则的一方,因此它可以选择不为自己执行规则。drkbr07n2#
根据定义,对象的单例类也继承了对象超类的单例类。
我们不要想当然地认为这是理所当然的,让我们弄清楚为什么要以这种方式实现它。
在Ruby中,有示例方法和类方法,而类方法实际上是单例类的示例方法:
如图所示:
现在,如果你创建一个子类
MySubClass
,它会从超类MyClass
继承示例方法和类方法:为了让它工作,必须为类和单例类都建立继承:
Ruby在内部对此进行了优化--单例类只在需要的时候创建,但从概念上讲,这就是发生的事情。
除此之外,
MyClass
和MySubClass
已经带有一些内置的类方法,最著名的是用于创建示例的.new
,还有.superclass
。你可能知道
.new
的默认实现是在幕后调用.allocate
的,所以在某个地方一定有一个包含这些方法的“根类”,因为它们是类方法,所以它必须位于单例类的顶部:这个神秘的顶级单例根类为所有其他类提供了基本的类方法,它是...
Class
!