2012-07-09 5 views
6

Quali sono le differenze tra questo:Qual è la differenza tra le definizioni dei moduli di nidificazione e l'utilizzo di :: in definition in ruby?

module Outer 
    module Inner 
    class Foo 
    end 
    end 
end 

e questo:

module Outer::Inner 
    class Foo 
    end 
end 

So che quest'ultimo esempio non funziona se Outer non è stato definito in precedenza, ma ci sono alcune altre differenze con costante ambito e potrei trovare la loro descrizione su SO o nella documentazione (incluso il libro Ruby di programmazione)

+0

penso "classe A :: B :: MyClass" fa lavoro, non è vero? – davidrac

+0

Sì, funziona, ma qual è la differenza tra 'classe A :: B :: MyClass; fine' e 'modulo A; modulo B; classe MyClass; fine; fine; END; '? –

risposta

3

c'è almeno una differenza: ricerca costante, controllare questo codice:

module A 
    CONST = 1 

    module B 
    CONST = 2 

    module C 
     def self.const 
     CONST 
     end 
    end 
    end 
end 

module X 
    module Y 
    CONST = 2 
    end 
end 

module X 
    CONST = 1 

    module Y::Z 
    def self.const 
     CONST 
    end 
    end 
end 

puts A::B::C.const # => 2, CONST value is resolved to A::B::CONST 
puts X::Y::Z.const # => 1, CONST value is resolved to X::CONST 
+0

Quindi, utilizza lo scope lessicale per le costanti e "salta sopra": quando si eseguono le definizioni del modulo di camminata, corretto? –

+0

non conosco i dettagli del loro algoritmo ma sembra decisamente così. sapendo che ti aiuta a evitare il debug dell'inferno a volte. Non conosco altre differenze tra 2 tipi di definizione di modulo/classe. – keymone

+0

Sì, questo combinato con l'autoloading di Rails può portare a qualche debug infernale :) –

7

Grazie alla keymone di answer I formulati corretta interrogazione Google e abbiamo trovato questo: Module.nesting and constant name resolution in Ruby

Utilizzando :: variazioni risoluzione portata costante

module A 
    module B 
    module C1 
     # This shows modules where ruby will look for constants, in this order 
     Module.nesting # => [A::B::C1, A::B, A] 
    end 
    end 
end 

module A 
    module B::C2 
    # Skipping A::B because of :: 
    Module.nesting # => [A::B::C2, A] 
    end 
end