0

我在访问嵌套模块中的模块常量时遇到问题。这是代码:

外部.rb

require 'inner.rb'

module Outer
  BASE_DIR = "cache/"
end

内部.rb

module Outer
  module Inner
    puts BASE_DIR
  end
end

如果我在 inner.rb 中运行代码,我会收到以下错误:

<module:Inner>': uninitialized constant Outer::Inner::BASE_DIR (NameError)

我认为由于在外部模块中声明了 BASE_DIR ,因此在内部模块中也应该可以访问它,但似乎并非如此。

4

2 回答 2

2

这是加载顺序的问题。将 require 替换为所需的实际代码表明您的代码按以下顺序加载:

module Outer
  module Inner
    puts BASE_DIR
  end
end

module Outer
  BASE_DIR = "cache/"
end

现在很容易看出为什么这不起作用。正如错误消息所暗示的那样,在您尝试访问它时根本没有定义常量。发生这种情况是因为不在方法定义中的每一段代码都将立即执行。然而,从方法访问常量是可能的:

module Outer
  module Inner
    def self.foo
      puts BASE_DIR
    end
  end
end

module Outer
  BASE_DIR = "cache/"
end

Outer::Inner.foo
# cache/

根据您的需要,有几种可能的解决方案:

  • 消除使用常量外部方法(可能不是一个选项)
  • 更改加载顺序(将 放在require文件末尾)
  • 将全局设置的存储委托给专用的类/模块
于 2013-10-21T07:15:11.523 回答
0

不,红宝石不会那样做。查看 ruby​​ 用于解析名称的祖先链。

所以你将不得不使用Outer::BASE_DIR

是关于 ruby​​ 类系统和 rails 自动加载的精彩讨论。

于 2013-10-21T05:53:49.493 回答