2013-03-06 61 views
2

an answer to a previous question所述,B < A是判斷類是否是另一類的子類的最簡單方法。然而,當B是單例類(即特徵類)時,這在Ruby 1.8(也是REE 1.8)中似乎失敗了。爲了說明:Ruby 1.8 vs. 1.9:確定Ruby單例類是否是另一個類的子類

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 << b; self; end)的祖先,它返回false當你在Ruby 1.8中檢查是否其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 << b; self; end).ancestors.include?(A)作爲一種解決方法,雖然它在技術上並不「正確」,因爲祖先列表還包含包含的模塊。

回答

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。

相關問題