2015-12-17 1 views
5

私はちょうどこれに固執してしまった。私は、モジュールを指定するには、::を使用してインデントを最小化しようとした場合、しかし、::を使用してモジュールを指定したときに、Rubyがより高いスコープでクラスを見つけられないのはなぜですか?

module Top 
    module Foo 
    class SomeTest < Test 
    end 
    end 
end 

module Top 
    class Test 
    end 

    module Foo 
    end 
end 

その後、私はこれを行うことにより、Testを拡張Foo内のクラスを定義することができます。このベースを取る

module Top::Foo 
    class Failure < Test 
    end 
end 

これはで失敗します。

NameError: uninitialized constant Top::Foo::Test

これはバグですか、それともRubyが変数名を解決する方法の論理的な結果ですか?

答えて

7

Is this a bug, or is it just a logical consequence

それは "癖" です。それはバグだと思う人もいます。

未解決の定数をルックアップするために使用される親スコープは、モジュールのネストによって決定されます。 module Top::Fooを使用すると、2つではなく1つのレベルの入れ子が作成されます。お守り:

module Top 
    module Foo 
    class SomeTest 
     Module.nesting # => [Top::Foo::SomeTest, Top::Foo, Top] 
    end 
    end 
end 

module Top::Foo 
    class SomeTest 
    Module.nesting # => [Top::Foo::SomeTest, Top::Foo] 
    end 
end 
+2

は私にはバグのような音:Pしかし、非常に有益な応答、私はそれバグ考えると言うでしょう、あなたに – Hubro

+0

に感謝、誰もがこの程度ルビーでバグレポートを発見しましたか?私は議論に貢献し、これを修正することに関わるものを見たいと思います。 –

+0

注:意図的な[ここ](https://bugs.ruby-lang.org/issues/11705) –

1

これは予想されます。 ::を使用すると、定数ルックアップの範囲が変更され、TestTop::Fooの下に定義されることが予想されます。

期待される結果を得るには、あなたが書くことができる:

module Top::Foo 
    class SomeTest < Top::Test 
    end 
end 

か:

module Top 
    class Foo::SomeTest < Test 
    end 
end 

かさえを:

class Top::Foo::SomeTest < Top::Test 
end 
関連する問題