Ruby - 词法范围与继承 [英] Ruby - Lexical scope vs Inheritance
问题描述
这是原始SO问题的延续:使用& ; ::"而不是模块......对于Ruby命名空间
This is a continuation this original SO question: Using "::" instead of "module ..." for Ruby namespacing
在最初的SO问题中,这里是我仍然无法理解的情景:
In the original SO question, here is the scenario presented which I'm still having trouble understanding:
FOO = 123
module Foo
FOO = 555
end
module Foo
class Bar
def baz
puts FOO
end
end
end
class Foo::Bar
def glorf
puts FOO
end
end
puts Foo::Bar.new.baz # -> 555
puts Foo::Bar.new.glorf # -> 123
有人可以提供一些解释为什么第一个电话返回555以及第二个电话返回的原因123?
Can someone provide some explanation behind why the first call is returning 555 and why the second call is returning 123?
推荐答案
您可以想到模块的每个外观
, class Something
或 def something
作为新网域的网关。当Ruby正在搜索已被引用的名称的定义时,它首先查找当前作用域(方法,类或模块),如果找不到它,它将返回每个包含网关并搜索那里的范围。
You can think of each appearance of module Something
, class Something
or def something
as a "gateway" into a new scope. When Ruby is searching for the definition of a name that has been referenced it first looks in the current scope (the method, class or module), and if it isn’t found there it will go back through each containing "gateway" and search the scope there.
在你的例子中,方法 baz
被定义为
In your example the method baz
is defined as
module Foo
class Bar
def baz
puts FOO
end
end
end
所以当试图确定 FOO
,首先检查类 Bar
,因为 Bar
不包含 FOO
搜索通过类Bar
网关进入 Foo
模块,这是包含范围。 Foo
确实包含一个常量 FOO
(555)所以这就是你看到的结果。
So when trying to determine the value of FOO
, first the class Bar
is checked, and since Bar
doesn’t contain a FOO
the search moves up through the "class Bar
gateway" into the Foo
module which is the containing scope. Foo
does contain a constant FOO
(555) so this is the result you see.
方法 glorf
定义为:
class Foo::Bar
def glorf
puts FOO
end
end
这里的网关是类Foo :: Bar
,所以当 FOO
isn时在栏内找到
网关通过 Foo
模块并直接进入顶层,其中有另一个 FOO
(123)这是显示的内容。
Here the "gateway" is class Foo::Bar
, so when FOO
isn’t found inside Bar
the "gateway" passes through the Foo
module and straight into the top level, where there is another FOO
(123) which is what is displayed.
注意如何使用类Foo :: Bar
创建一个网关,跳过 Foo
的范围,但是模块Foo; class Bar ...
打开两个单独的网关
Note how using class Foo::Bar
creates a single "gateway", skipping over the scope of Foo
, but module Foo; class Bar ...
opens two separate "gateways"
这篇关于Ruby - 词法范围与继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!