Can anonymous modules and class be nested in Ruby?

蓝咒 提交于 2019-12-10 06:54:33

问题


I can define an anonymous class within an anonymous module:

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

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

Is the above equivalent to:

m = Module.new
c = Class.new

In other words: does the concept of "nesting" actually apply to anonymous modules?


回答1:


It is not about being anonymous. Assigning a dynamically created class to a constant makes it named:

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

Yet it still doesn't nest further:

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

Or even about being dynamic for that matter:

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

It's about scope gates.


As far as constants are concerned, there are only two scope gates - the keywords class and module.

Nesting is done purely syntactically. That is why you get the weird:

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

So if Ruby sees the keywords class or module, it nests the "current node" further. When the closing end is found, it goes up the tree. When a new constant is being defined, it places it in the current node.



来源:https://stackoverflow.com/questions/40890576/can-anonymous-modules-and-class-be-nested-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!