2016-01-07 14 views
5

C'è un modo per accedere a baz_method all'interno di class Qux senza menzionare prima lo spazio dei nomi del modulo? Quando ci sono molti moduli annidati il ​​codice non sembra pulito.Come accedere ai metodi del modulo genitore/fratello

module Foo 
    module Bar 
    module Baz 
     class Qux 
     def self.qux_method 
      Foo::Bar::Baz.baz_method 
     end 
     end 
     def self.baz_method 
     end 
    end 
    end 
end 
+0

Questo è l'intero scopo del namespace. – archana

risposta

9

Le costanti vengono esaminate prima nei moduli che contengono lessicalmente e quindi nella catena di ereditarietà.

module Foo 
    module Bar 
    module Baz 
     class Qux 
     def self.qux_method 
      Baz.baz_method  
     end 
     end 
     def self.baz_method 
     end 
    end 
    end 
end 

Questo funzionerà, perché la costante Baz saranno prima cercate nel modulo lessicale allegando (classe) Qux, dove non viene trovato. La ricerca continua nel modulo lessicale Baz, dove non è stato trovato. Pertanto, verrà successivamente esaminato nel modulo che include lessicamente Bar, dove è stato trovato e e la ricerca si interrompe.

Nota: si scrive nel titolo:

Rubino, genitore di accesso/fratelli metodi modulo

Questo è sbagliato. Questi moduli non sono né genitori né fratelli. Non c'è eredità qui. Esiste, infatti, no rapporto tra i moduli su tutti. C'è solo una relazione tra le costanti e i moduli: le costanti appartengono ai moduli.

Il modulo dichiarazioni sono annidati lessicale, ma i moduli stessi non sono.

2

Nota: A meno che non si sta cercando in modo esplicito per l'accesso relativo modulo, questo metaprogrammazione non è necessaria. Utilizzare invece @ drhining's solution.

Si può salire dinamicamente la gerarchia modulo utilizzando Module#nesting:

module Foo 
    module Bar 
    module Baz 
     class Qux 
     def self.qux_method 
      Module.nesting[1].baz_method 
     end 
     end 

     def self.baz_method 
     puts "foo!" 
     end 
    end 
    end 
end 

In questa situazione, Module.nesting darà il seguente (quando viene chiamato in qux_method): [Foo::Bar::Baz::Qux, Foo::Bar::Baz, Foo::Bar, Foo]

Nota però che questo non è un riferimento non ambiguo a Baz, ma piuttosto a qualsiasi cosa si trovi ad un livello nella catena di moduli.

+0

'[Qux, Baz, Bar, Foo]' non è chiaro. Non intendi '[Foo :: Bar :: Baz :: Qux, Foo :: Bar :: Baz, Foo :: Bar, Foo]'? – sawa

+0

@sawa: non intendevo letteralmente, ma immagino di non averlo chiarito. Modificata la tua versione con spazi dei nomi completi. – Linuxios

+0

"questo non è un riferimento univoco a Baz": come può essere ambiguo? Puoi fare un esempio? –

4

Non è necessario specificare l'intera catena del namespace. Hai solo bisogno di quanto è necessario per disambiguare la costante. Basta usare Baz.baz_method.

module Foo 
    module Bar 
    module Baz 
     class Qux 
     def self.qux_method 
      Baz.baz_method 
     end 
     end 

     def self.baz_method 
     end 
    end 
    end 
end 
+0

Duh. Non posso credere di aver dimenticato questo scritto la mia risposta. +1. – Linuxios

+0

Non sapevo però di 'Module.nesting'. Non è necessario qui ma sembra utile – drhining

+0

È, se stai facendo qualcosa di stravagante. – Linuxios

Problemi correlati