简体   繁体   English

BasicObject 的 singleton_class 的超类如何以及为什么是 Ruby 中的 Class 类?

[英]How and why is the super class of singleton_class of BasicObject is Class class in Ruby?

By definition, a singleton class of an object also inherits the singleton class of the superclass of the object.根据定义,一个对象的单例类也继承了该对象超类的单例类。 The BasicObject in ruby doesn't have any superclass as it is the most basic level class ruby 中的BasicObject没有任何超类,因为它是最基本的级别类

>> BasicObject.superclass
=> nil

But when the same method called on its singleton class, it results:但是当同一个方法调用它的单例类时,结果是:

>> BasicObject.singleton_class.superclass
=> Class

and also why no other object in ruby have the Class class as its superclass?以及为什么 ruby 中没有其他对象将Class类作为其超类?

How the logic behind the superclass of singleton_class of BasicObject is implemented in Ruby? BasicObject的singleton_class超类背后的逻辑在Ruby中是如何实现的?

In general, the superclass of the singleton class of an object is the class of the object.一般来说,对象的单例类的超类就是对象的类。 Ie for any object foo with a singleton class, the following holds:即对于具有单例类的任何对象foo ,以下内容成立:

foo.singleton_class.superclass == foo.class

However, for classes, this would be somewhat boring: the class of every class is Class , so the superclass of every class's singleton class would always be Class .然而,对于类来说,这会有些无聊:每个类的类都是Class ,所以每个类的单例类的超类总是Class

That is not particularly useful, since it would break some reasonable assumptions.这不是特别有用,因为它会打破一些合理的假设。 For example, if I have something like this:例如,如果我有这样的东西:

class Super
  def self.super_singleton_method; end
end

class Sub < Super; end

I would expect to be able to call Sub.super_singleton_method .我希望能够调用Sub.super_singleton_method However, in order to do this, Super.singleton_class needs to be somewhere in the method lookup chain of Sub.singleton_class .但是,为了做到这一点, Super.singleton_class需要位于Sub.singleton_class的方法查找链中的某个位置。

So, for classes, the rule is somewhat different: the superclass of the singleton class of a class is the singleton class of the superclass of the class.所以,对于类,规则有些不同:一个类的单例类的超类是该类的超类的单例类。 Ie for any class Foo , the following holds:即对于任何类Foo ,以下成立:

Foo.singleton_class.superclass == Foo.superclass.singleton_class

If you want, you can check whether this is true for every class in your system:如果需要,您可以检查系统中的每个类是否都是这样:

ObjectSpace.each_object(Class).select do |klass|
  klass.singleton_class.superclass != klass.superclass.singleton_class
end
#=> [BasicObject]

So, as you can see, this property does hold for all classes except BasicObject .因此,如您所见,此属性适用BasicObject之外的所有类

The simple answer for why BasicObject is different is that BasicObject has no superclass, and thus we cannot apply the rule. BasicObject为何不同的简单答案是BasicObject没有超类,因此我们无法应用该规则。 So, we fall back on the more general rule for all objects that因此,我们求助于所有对象的更一般规则

foo.singleton_class.superclass == foo.class

And BasicObject 's class is Class , therefore, BasicObject的类是Class ,因此,

BasicObject.singleton_class.superclass == BasicObject.class
BasicObject.singleton_class.superclass == Class

and also why no other object in ruby have the Class class as its superclass?以及为什么 ruby 中没有其他对象将Class类作为其超类?

The only reason to inherit from Class would be to override the behavior of how inheritance or method lookup works in Ruby.Class继承的唯一原因是要覆盖 Ruby 中继承或方法查找工作方式的行为。 But Ruby does not allow to override this.但是 Ruby 不允许覆盖它。 How inheritance and method lookup works is part of the language specification and cannot be changed.继承和方法查找的工作方式是语言规范的一部分,无法更改。 Therefore, inheriting from Class is illegal:因此,从Class继承是非法的:

class MyClass < Class; end
# can't make subclass of Class (TypeError)

Thus there cannot be any object which has Class as its superclass, except singleton classes of classes.因此,除了类的单例类之外,不可能有任何对象将Class作为其超类。 (Ruby can of course break its own rules since it is the one that makes the rules.) (Ruby 当然可以打破自己的规则,因为它是制定规则的人。)

How the logic behind the superclass of singleton_class of BasicObject is implemented in Ruby? BasicObject的singleton_class超类背后的逻辑在Ruby中是如何实现的?

It isn't.它不是。 You cannot explain how this works in Ruby, since it is part of the definition of Ruby itself.你无法解释这在 Ruby 中是如何工作的,因为它是 Ruby 本身定义的一部分。

It is similar to how Class is a subclass of Module , but Module is a class, ie an instance of Class .它类似于ClassModule的子类,但Module是一个类,即Class的实例。 You cannot explain this from within Ruby using the rules of Ruby, but the Ruby implementation can, of course, set things up so that this works, since the Ruby implementation itself does not have to abide by the rules of Ruby: it is the one enforcing the rules, so it can just choose not to enforce them for itself.你无法使用 Ruby 规则从 Ruby 内部解释这一点,但是 Ruby 实现当然可以设置它以使其有效,因为 Ruby 实现本身不必遵守 Ruby 规则:它是唯一的执行规则,因此它可以选择不为自己执行规则。

By definition, a singleton class of an object also inherits the singleton class of the superclass of the object.根据定义,一个对象的单例类也继承了该对象超类的单例类。

Instead of taking this for granted, let's figure out why it was implemented this way.与其认为这是理所当然的,不如让我们弄清楚为什么要这样实现。

In Ruby, there are instance methods and class methods.在 Ruby 中,有实例方法和类方法。 The class methods however are in fact instance methods of the singleton class:然而,类方法实际上是单例类的实例方法:

class MyClass
  def foo
  end

  def self.bar
  end
end

MyClass.instance_methods(false)
#=> [:foo]

MyClass.singleton_class.instance_methods(false)
#=> [:bar]

As a diagram:如图:

MyClass  --->  #<Class:MyClass>
foo            bar

Now, if you create a subclass MySubClass , it inherits both, the instance methods and the class methods from its superclass MyClass :现在,如果您创建一个子类MySubClass ,它会从其超类MyClass继承实例方法和类方法:

class MySubClass < MyClass
end

MySubClass.instance_methods
#=> [:foo, ...]

MySubClass.singleton_class.instance_methods
#=> [:bar, ...]

To get this working, the inheritance has to be established for both, the classes and the singleton classes:为了让它工作,必须为类和单例类建立继承:

MyClass     --->  #<Class:MyClass>
foo               bar
    ^                    ^
    |                    |
MySubClass  --->  #<Class:MySubClass>

Ruby optimized this internally – the singleton classes are only created when needed. Ruby 在内部对此进行了优化——单例类仅在需要时创建。 But conceptually, this is what happens.但从概念上讲,这就是发生的事情。

Apart from that, MyClass and MySubClass already come with some built-in class methods, most notably .new which is used to create instances, but also .superclass .除此之外, MyClassMySubClass已经带有一些内置的类方法,最著名的是用于创建实例的.new ,还有.superclass

You might know that the default implementation of .new calls .allocate under the hood.您可能知道.new的默认实现在后台调用.allocate So somewhere there must be a sort of "root class" which contains these methods.所以某处必须有一种包含这些方法的“根类”。 And since they are class methods, it must sit on top of the singleton class side:由于它们是类方法,它必须位于单例类端之上:

                  <singleton root class>
                  new
                  allocate
                  superclass
                         ^
                         |
                        ...
                         |
MyClass     --->  #<Class:MyClass>
foo               bar
    ^                    ^
    |                    |
MySubClass  --->  #<Class:MySubClass>

And this mysterious top level singleton root class that provides the fundamental class methods for all other classes is... Class !而这个为所有其他类提供基本类方法的神秘顶级单例根类是…… Class

Class.instance_methods(false)
#=> [:allocate, :superclass, :subclasses, :new]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM