2017-04-03 53 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] 

或者,您可以使用ObjectSpace#each_object獲得A的後裔。

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]} 
相關問題