2

我曾相信

module A
  module B
    ...
  end
end

和(前提A是预先定义了模块):

module A::B
  ...
end

是等价的,但事实证明不是。鉴于:

module A
  C = :foo
end

这两种形式的行为不同:

module A
  module B
    puts C
  end
end
# => :foo

module A::B
  puts C
end
# => NameError: uninitialized constant A::B::C

这种差异背后的逻辑是什么?特别是,为什么不能以第二种形式A::B访问A::C(尽管它可以以第一种形式)?


更新

我在 Ruby 核心上找到了一些相关的帖子:

4

1 回答 1

1

Module::nesting是在这里回答你的好工具。正如文档所说 -返回嵌套在调用点的模块列表。

这是以下原因不起作用的原因:

module A
  C = :foo
end

module A::B
  puts C
end

为了解释这一点,我会写如下内容:

module A
  C = :foo
end

module A::B
  $a = Module.nesting
end
$a # => [A::B]

因此,从 的输出中$a可以清楚地看出为什么常量C不可访问。

以下代码确实有效的原因:

module A
  C = :foo
end
module A
  module B
    puts C
  end
end

为了解释这一点,我会写如下内容:

module A
  C = :foo
end

module A
  module B
    $a = Module.nesting
  end
end
$a # => [A::B, A]

因此,从 的输出中$a可以清楚地看出为什么C可以访问常量。

在这里阅读(你想知道的关于 Ruby 中的常量查找的一切)是我刚刚发现的一个很好的资源。

于 2013-09-28T19:14:31.590 回答