匿名模块和class可以嵌套在Ruby中吗?
Can anonymous modules and class be nested in Ruby?
我可以在匿名模块中定义一个匿名 class:
c = nil
m = Module.new do
c = Class.new
end
m #=> #<Module:0x007fad3a055660>
c #=> #<Class:0x007fad3a0555e8>
以上是否等同于:
m = Module.new
c = Class.new
换句话说:"nesting"的概念真的适用于匿名模块吗?
这与匿名无关。将动态创建的 class 分配给常量使其命名为:
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
这是关于作用域门的。
就常量而言,只有两个作用域门——关键字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
因此,如果 Ruby 看到关键字 class
或 module
,它会进一步嵌套 "current node"。当找到关闭的 end
时,它会在树上向上移动。当一个新常量被定义时,它将它放在当前节点中。
我可以在匿名模块中定义一个匿名 class:
c = nil
m = Module.new do
c = Class.new
end
m #=> #<Module:0x007fad3a055660>
c #=> #<Class:0x007fad3a0555e8>
以上是否等同于:
m = Module.new
c = Class.new
换句话说:"nesting"的概念真的适用于匿名模块吗?
这与匿名无关。将动态创建的 class 分配给常量使其命名为:
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
这是关于作用域门的。
就常量而言,只有两个作用域门——关键字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
因此,如果 Ruby 看到关键字 class
或 module
,它会进一步嵌套 "current node"。当找到关闭的 end
时,它会在树上向上移动。当一个新常量被定义时,它将它放在当前节点中。