【问题标题】:Ruby 1.8 vs. 1.9: Determining whether a Ruby singleton class is a subclass of another classRuby 1.8 与 1.9:确定 Ruby 单例类是否是另一个类的子类
【发布时间】:2013-02-22 00:11:12
【问题描述】:

正如an answer to a previous question 中提到的,B < A 是确定一个类是否是另一个类的子类的最简单方法。但是,当B 是单例类(即特征类)时,这在 Ruby 1.8(也是 REE 1.8)中似乎失败了。举例说明:

class A; end
class B < A; end

b = B.new

B.ancestors                         # => [B, A, Object, Kernel] (also BasicObject in 1.9)
(class << b; self; end).ancestors   # => [B, A, Object, Kernel] (also BasicObject in 1.9)

B < A                               # => true
(class << b; self; end) < A         # => true in 1.9; false in 1.8

如您所见,即使 A 被列为单例类 (class &lt;&lt; b; self; end) 的祖先,当您检查它是否是 Ruby 1.8 中 A 的子类时,它也会返回 A(但正确在 1.9 中返回 true)。遵循#superclass 链似乎说明了为什么会出现这种情况:

B.superclass
  # => A

(class << b; self; end).superclass
  # => B in 1.9
  # => singleton class of B in 1.8

(class << b; self; end).superclass.superclass
  # => A in 1.9
  # => singleton class of Class in 1.8

有谁知道这是 1.8 中的一个错误,恰好在 1.9 中修复,或者可能是在 1.9 中有意更改的预期行为?我已尝试在其他地方找到有关此问题的提及或文档,但找不到任何东西。

由于这个问题,有谁知道 在 Ruby 1.8 中检查单例类是否是 A 的子类的最佳方法是什么?我一直在做 (class &lt;&lt; b; self; end).ancestors.include?(A) 作为解决方法,尽管它在技术上并不“正确”,因为祖先列表也包含包含的模块。

【问题讨论】:

    标签: ruby inheritance subclass superclass eigenclass


    【解决方案1】:

    我建议:

    class Object; def metaclass; class << self; self; end; end; end
    
    class A; end
    class B < A; end
    
    b = B.new
    
    b.metaclass < A.metaclass || b.metaclass < A
    

    在 Ruby 1.8、1.9 和 2.0 中测试。

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 2011-07-01
      • 1970-01-01
      • 2010-10-21
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2020-08-05
      • 2011-11-26
      相关资源
      最近更新 更多