2011-10-19 21 views
35

Così Module può essere utilizzato in Ruby per fornire namespacing oltre a mixins, come così:Qual è la differenza tra queste convenzioni dello spazio dei nomi di Ruby?

module SomeNamespace 
    class Animal 

    end 
end 

animal = SomeNamespace::Animal.new 

Ma ho visto anche i seguenti usati:

module SomeNamespace 
end 

class SomeNamespace::Animal 

end 

animal = SomeNamespace::Animal.new 

mia domanda è come si' sei diverso (se lo sono) e quale è più idiota di Ruby?

risposta

37

La differenza sta nella nidificazione.

Nell'esempio seguente, è possibile vedere che il metodo precedente che utilizza la classe Foo, può ottenere le variabili costanti dell'oscilloscopio esterno BAR_A senza errori.

Nel frattempo, la classe Baz bombarderà con un errore di costante non inizializzata A :: B :: Baz :: BAR_A. Poiché non introduce A :: * implicitamente, solo A :: B :: * esplicitamente.

module A 
    BAR_A = 'Bar A!' 
    module B 
    BAR_B = 'Bar B!' 
     class Foo 
     p BAR_A 
     p BAR_B 
     end 
    end 
end 

class A::B::Baz 
    p BAR_A 
    p BAR_B 
end 

Entrambi i comportamenti hanno il loro posto. Secondo me, non c'è un vero consenso nella comunità su quale sia l'One True Ruby Way (tm). Io personalmente uso il primo, il più delle volte.

5

L'unica differenza tra i due approcci è che il secondo getterà uninitialized constant Object::SomeNamespace se lo spazio dei nomi non è stato precedentemente dichiarato.

Se dichiarato in un singolo file, opterei per il primo perché non è necessario ripetere SomeNamespace.

Quando si utilizzano più file Io uso anche il secondo, per evitare di incorrere nel seguente problema:

# in a.rb 
require 'b' 

module SomeNamespace 
    def self.animal 
    Animal.new 
    end 
end 

# in b.rb 
class SomeNamespace::Animal 

end 

# irb 
require 'a' # explodes with the uninitialized constant error 

Questo esempio può essere forzato, ma è facile da innescare, se la vostra base di codice è un po ' più grande. Di solito uso il modo esplicito (il tuo primo) per evitarlo.

Una cosa che può essere utile quando si utilizza il secondo modulo è che rileverà errori di battitura nello spazio dei nomi.

Non sembra esserci un modo consolidato per creare spazi dei nomi, Devise ad esempio unisce entrambi gli approcci: first one, second one.

Problemi correlati