Ruby - 词法范围与继承 [英] Ruby - Lexical scope vs Inheritance

查看:93
本文介绍了Ruby - 词法范围与继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是原始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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆