2012-07-09 5 views
6

何をこの間の違いされていますモジュール定義を入れ子にすることと、ルビの定義で::を使うことの違いは何ですか?

module Outer 
    module Inner 
    class Foo 
    end 
    end 
end 

と、この:

module Outer::Inner 
    class Foo 
    end 
end 

は、私がOuterは先に定義されていない場合は、後者の例では動作しません知っているが、一定の持つ他のいくつかの違いがあります(Rubyブックを含む)

+0

を変更仕事じゃない? – davidrac

+0

はい、それは動作しますが、 'class A :: B :: MyClass; end 'と 'module A;モジュールB;クラスMyClass。終わり;終わり;終わり? –

答えて

3

少なくとも1つの相違 - 定数ルックアップがある場合、このコードをチェックしてください:

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

それで、定数のためのレキシカルスコープを使用し、モジュール定義を歩いているときに "jump over" ::正しい? –

+0

彼らのアルゴリズムの詳細はわかりませんが、間違いなくそのように見えます。それを知ることは時には地獄のデバッグを避けるのに役立ちます。私はモジュール/クラス定義の2種類の間の他の違いを知らない。 – keymone

+0

はい、これはRailsの自動ロードと組み合わせると、いくつかの地獄のようなデバッグにつながる可能性があります:) –

7

私は正しい、Googleのクエリを策定し、これを見つけたkeymoneのanswerのおかげ:::を使用してModule.nesting and constant name resolution in Ruby

は、私が "クラスA :: B :: MyClassのは" ないと思う一定の範囲の解像度

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 
関連する問題