根据定义,对象的单例类也继承该对象的超类的单例类.Ruby中的BasicObject没有任何超类,因为它是最基本的级别类

>> BasicObject.superclass
=> nil

但是,当相同的方法调用它的Singleton类时,结果是:

>> BasicObject.singleton_class.superclass
=> Class

还有,为什么Ruby中没有其他对象将Class类作为其超类?

BasicObject的Singleton_Class超类背后的逻辑是如何在Ruby中实现的?

推荐答案

通常,对象的单例类的超类是该对象的类.即,对于具有单例类的任何对象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本身定义的一部分.

这类似于ClassModule的子类,但Module是一个类,即Class的实例.您不能使用Ruby的规则从Ruby内部解释这一点,但Ruby实现当然可以进行设置,以使其工作,因为Ruby实现本身不必遵守Ruby的规则:它是执行规则的人,所以它可以 Select 不为自己执行规则.

Ruby相关问答推荐

如何使用另一个Ruby 中的Ruby 中的区域设置?

扫描不带空格的字符串中的单词

在 Ruby 中,如何从派生类中重写同一方法的不同方法调用基类方法?

每次调用返回新的 REST 响应的 Ruby Rspec class_double

如何使用 gsub 删除返回字符串中的/和/i?

令人惊讶的有效 Ruby 语法:% 无处不在

从href html标签中提取带有Ruby中nokogiri的链接(URL)?

创建一个哈希值作为数组和默认值作为空数组

如何在两个浮点数之间的范围内最好地创建一个随机浮点数

为什么 RuboCop 建议用 Array.new 替换 .times.map?

Ruby 中的 -> (stab) 运算符是什么?

group_by 在 rails by 2 或更多属性

如何在Ruby中获取终端窗口的宽度

在 Rails 中,如何向 String 类添加新方法?

在 ruby​​ 异常中捕获行号

如何在 Ruby 中创建可重用的块/proc/lambda?

ActiveSupport::Memoizable 指的是哪种 Ruby memoize 模式?

Ruby Koans 的 test_sharing_hashes 中的附加问题的答案是什么?

Ruby 中的 each 和 collect 方法有什么不同

如何在 Rails 应用程序中使用 httparty 的基本身份验证?