2017-04-03 7 views
0

私の質問はthis questionとは異なることに注意してください。クラスのすべての子孫(子孫の子孫を含む)を求めているからです。`self.inherited`を使ってRubyでクラスのすべての子孫を取得するには?

また、私はそれがすべてのクラスを取得し、子孫のためのフィルタリングをより速く道だから

class Animal 
    def self.inherited(subclass) 
    @descendants = [] 
    @descendants << subclass 
    end 

    def self.descendants 
    puts @descendants  
    end 
end 

のようなものを使用することを好むだろう。

+1

レイジーは '@descendants || = []インスタンス化し'と設定が完了しているを書くことができます。しかし、これは子孫の子孫のための箱からは機能しません。リンクされた答えは、ツリー全体(子孫の子孫)のトリックを返します。 – mudasobwa

答えて

1
class A 
    singleton_class.send(:attr_reader, :descendants) 
    @descendants = [] 
    def self.inherited(subclass) 
    A.descendants << subclass 
    end 
end 

A.methods(false) 
    #=> [:inherited, :descendants, :descendants=] 

class B < A; end 
class C < B; end 
class D < B; end 
class E < C; end 
class F < E; end 

A.descendants 
    #=> [B, C, D, E, F] 

また、あなたはAの子孫を得ることがObjectSpace#each_objectを使用することができます。

ObjectSpace.each_object(Class).select { |c| c < A } 
    #=> [F, E, D, C, B] 

あなたは

arr = [B, C, D, E, F] 

の順序を取得したい場合は、

(arr << A).each_with_object({}) { |c,h| h[c] = 
    arr.each_with_object([]) { |cc,a| a << cc if cc.superclass == c } } 
    #=> {B=>[C, D], C=>[E], D=>[], E=>[F], F=>[], A=>[B]} 
関連する問題