2012-03-24 14 views
5

Jeśli masz:Jak znaleźć wszystkie moduły i klasy w module rekursywnie?

module A 
    class B 
    end 
end 

można znaleźć B i podobne zajęcia poprzez A.constants. Jednak w Ruby 1.9.3 nie można uzyskać B, jeśli znajduje się on w innym module. W Ruby 1.8.7 możesz.

module A 
    module Aa 
    class B 
    end 
    end 
end 

Jak uzyskać B z pierwszego poziomu A? Chciałbym jako wyjście jest tablicą stałych, które obejmują wszystkie zajęcia, takie jak B, ale w dowolnym miejscu w module A.

+0

Co masz na myśli, że nie możesz uzyskać B? Mogę zrobić A :: Aa :: B.new, działa – megas

+0

Czy 'MyModule.constants.select {| c | Class === MyModule.const_get (c)} 'działa dla ciebie? http://stackoverflow.com/questions/833125/find-classes-available-in-a-module – ScottJShea

+1

Tak, możesz utworzyć instancję bezpośrednio. Ale w jaki sposób zapełnisz tablicę symboli, które wymieniają klasy takie jak B? Scott: to nie zadziała dla Ruby 1.9.3 (dla Rubiego 1.8.7). Stałe nie zawierają modułów z jakiegoś powodu. – Jade

Odpowiedz

12
class Module 
    def all_the_modules 
    [self] + constants.map {|const| const_get(const) } 
     .select {|const| const.is_a? Module } 
     .flat_map {|const| const.all_the_modules } 
    end 
end 

A.all_the_modules 
# => [A, A::Aa, A::Aa::B] 

Kod ten pęknie jeśli masz okrągłe nazw, aka A::Aa::B.const_set(:A, A).

+0

Niesamowite, dziękuję! – Jade

+1

fajne. Dzięki! FYI. http://www.ruby-doc.org/core-2.0.0/Module.html#method-i-const_get – Juguang

+0

@Juguang Wydaje się być rubinem 2.0. http://ruby-doc.org/core-1.9.3/Module.html#method-i-const_get – Reactormonk

Powiązane problemy