嵌套与命名空间运算符

时间:2013-09-28 18:56:37

标签: ruby module namespaces

我相信

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核心上发现了一些相关帖子:

1 个答案:

答案 0 :(得分: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可以访问。

在这里阅读(Everything you ever wanted to know about constant lookup in Ruby)是我刚刚找到的一个很好的资源。