2

前の質問への回答で述べたようにB < A、クラスが別のクラスのサブクラスであるかどうかを判断する最も簡単な方法です。ただし、Ruby 1.8 (REE 1.8 も同様)Bがシングルトン クラス (つまり、eigenclass) の場合、これは失敗するようです。説明する:

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の祖先としてリストされていますが、Ruby 1.8ではサブクラスかどうかを確認すると返されます(ただし、1.9 では正しく返されます)。チェーンをたどると、これが当てはまる理由がわかります。class << b; self; endfalseAtrue#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.9 で修正された 1.8 のバグなのか、それとも 1.9 で意図的に変更された予想される動作なのか、誰にもわかりませんか? この問題に関する言及やドキュメントを他の場所で見つけようとしましたが、何も見つかりませんでした。

そして、この問題のために、シングルトン クラスがRuby 1.8のサブクラスであることを確認する最良の方法をA誰か知っていますか? (class << b; self; end).ancestors.include?(A)祖先のリストには含まれているモジュールも含まれているため、技術的には「正しい」わけではありませんが、回避策として行ってきました。

4

1 に答える 1

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でテスト済み。

于 2013-03-11T22:36:11.633 に答える