2011-10-19 12 views
35

Moduleはそうと、ミックスインに加えて、名前空間を提供するために、Rubyで使用できるように:これらのRuby名前空間の規則の違いは何ですか?

module SomeNamespace 
    class Animal 

    end 
end 

animal = SomeNamespace::Animal.new 

しかし、私はまた、次のように使用さ見てきました:

module SomeNamespace 
end 

class SomeNamespace::Animal 

end 

animal = SomeNamespace::Animal.new 

私の質問は、彼らが「どのように(もしあれば)異なっていて、もっと慣れ親しんだRuby?

答えて

37

違いはネスティングにあります。

以下の例では、クラスFooを使用していた以前のメソッドでは、エラーなしで外部スコープの定数変数BAR_Aを取得できます。

一方、クラスBazは、初期化されていない定数A :: B :: Baz :: BAR_Aのエラーで爆弾を爆発させます。暗黙のうちにA :: *を持ち込まないので、A :: B :: *だけを明示的に持ちます。

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 

どちらの動作もその場所にあります。一つの真のRuby Way(tm)がどれであるかに関して、私の意見ではコミュニティに本当のコンセンサスはありません。私は個人的に前者を使います。

5

2つの方法の唯一の違いは、名前空間が以前に宣言されていない場合は、uninitialized constant Object::SomeNamespaceが返される点です。

1つのファイルで宣言すると、最初に1つを選択すると、SomeNamespaceを繰り返す必要がなくなります。

私はまた、次のような問題に実行しないように、第二いずれかを使用する複数のファイルを使用して:あなたのコードベースが少しある場合は、この例では、工夫することができる

# 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 

が、それをトリガーするのは簡単ですより大きい。私は通常、これを避けるために明示的な方法(あなたの最初の方法)を使用します。

2つ目のフォームを使用するときに役立つものは、名前空間の誤植を検出することです。

名前空間を作成する方法は確立されていないようですが、Deviseは両方の方法を組み合わせて使用​​しています:first onesecond one

関連する問題