2013-07-11 14 views
7

ネストされたモジュールを再オープンするのは、使用する構文によって結果が異なるのはなぜですか?たとえば、これは正常に動作します:Rubyでネストされたモジュール異常を再オープンしました

module A 
    module E 
    end 
end 
module A 
    module E 
    def E.e 
    end 
    end 
end 

しかし、この:

module A 
    module E 
    end 
end 
module A::E 
    def E.e 
    end 
end 

はエラーを与える:

reopen.rb:6:in `<module:E>': uninitialized constant A::E::E (NameError) 
from reopen.rb:5:in `<main>' 

誰かがこのアウトポイントの前に(、回避策はselfの代わりを使用することですEeを定義するときのモジュール名ですが、実際にはこの投稿のポイントではありません)

+2

これはどういう意味ですか? –

+0

フェアポイント - 言い換えられた。興味深いもの: –

答えて

4

moduleキーワードは、モジュールの既存の名前への参照を確認する名前空間コンテキストを設定します。これらの名前空間は、内部(inner-to-outer)で検索され、モジュール(およびクラス)名への参照を解決します。両方のあなたの例では何が起こる

module A 
    module E 
    end 
end 
module A 
    def E.e 
    end 
end 

はRubyが見ていることである:あなたがmodule Eブロック内E.eを定義する必要があるかもしれないようなあなたの最初の例では

は、それに見えますが、実際に、あなたはしないでください現在の名前空間を返し、モジュール名として<namespace>::Eを試します。だから両方の例で、最初にチェックするのは実際には存在しないA::E::Eです。その後、次のコンテキストに戻ります。最初の例ではA::Eが有効であり、2番目の例では、それはちょうどEではありません。それがスローするエラーは、チェックしたファーストネームに関係します。

+1

IMO 'module A :: E'はネストされたコンテキストをネストされた名前で作成していますが、これはバグです。もしそれが: モジュールA モジュールE ... ' と等価であれば、それは名前空間についての通常の直感にはるかに近いと言えます。 –

+0

はい、常に 'module'ブロック内に単一のコンテキストを作成します。それは少なくともその点で自己矛盾しています。歴史的な理由以外は別の方法で動かすことができない理由は見当たりません。現在の行動に依存するコードが存在するかもしれません.EとA :: Eの両方が定義されています例えば。 –

+0

十分に公正です。おそらく、ここで問題を提起すれば、Rubyの将来のバージョンに浸透する可能性があります。 –

関連する問題