2016-11-30 11 views
4

私は匿名のモジュール内で匿名クラスを定義することができます匿名のモジュールとクラスをRubyにネストできますか?

つまり
m = Module.new 
c = Class.new 

c = nil 
m = Module.new do 
    c = Class.new 
end 

m #=> #<Module:0x007fad3a055660> 
C#=> #<Class:0x007fad3a0555e8> 

はに上記同等です「ネスト」の概念は、実際に匿名のモジュールに適用されていますか?

+0

「定義」の下に定義 –

+1

興味深い匿名モジュールはModule.nestingに登録されていません –

+0

@SergioTulentsev私の質問に言い換えれば、まったく入れ子がないかもしれません。 – Stefan

答えて

2

匿名ではありません。

Foo = Class.new # => Foo 
foo = Class.new # => #<Class:0x007fe5dd45d650> 

しかし、それはさらに、巣ません:定数に動的に作成されたクラスを割り当てることが名付けなり

module Bar 
    Baz = Module.new do 
    p Module.nesting # => [Bar] 
    end 
end 

、あるいはそのことについては、動的であることについて:

module Quz 
    eval 'module Qux; p Module.nesting; end' # => [Quz::Qux, Quz] 
end 

これはスコープゲートに関するものです。キーワードclassmodule -


は限り定数が懸念しているように、2つのだけのスコープゲートがあります。

ネスティングは純粋に構文的に行われます。あなたは奇妙なを取得する理由は次のとおりです。Rubyのキーワードclassまたはmoduleを見れば

module Do 
    X = 42 
end 

module Do 
    module Re 
    p Module.nesting # => [Do::Re, Do] 
    p X    # => 42 
    end 
end 

module Do::Mi 
    p Module.nesting # => [Do::Mi] 
    p X # => uninitialized constant 
end 

Do.module_eval { p X } # => uninitialized constant 
Do.instance_eval { p X } # => uninitialized constant 

だから、それはさらに「現在のノード」を入れ子にします。終了endが見つかると、ツリーの上に上がります。新しい定数が定義されると、それは現在のノードに配置されます。

+0

'Module.nesting'は、定数ルックアップに使用されるモジュールのスタックです。すべての 'module'(または' class')キーワードは、任意のモジュールをスタックにプッシュします( 'end'でポップする)。そして、一番上の要素は新しい定数のプレフィックスとして機能します。 – Stefan

+0

@Stefan正確に。 – ndn

+0

さらに、_constants_のみが格納され、暗黙の階層を形成します。現在のネストは一時的なもので、どこにも格納されていません。同じモジュールを別のネストで再オープンすることができます。私は結論づけます:モジュールとクラスはネストすることはできませんが、定数だけができます。あれは正しいですか? – Stefan

関連する問題