在嵌套模块中访问常量

问题描述:

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

outer.rb

require 'inner.rb' 

module Outer 
    BASE_DIR = "cache/" 
end 

inner.rb

module Outer 
    module Inner 
    puts BASE_DIR 
    end 
end 

如果我在inner.rb运行代码我得到以下错误:

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

我以为,既然在外部模块中声明的BASE_DIR也应该可以在内部模块中访问,但似乎并非如此。

+0

您帖子顶部的错误消息是什么?我*地删除它。 –

+0

错误的复制/粘贴。感谢编辑。 – Chris911

这是加载顺序的问题。更换与实际需要的代码需要揭示你的代码是按以下顺序加载:

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在文件的结尾)
  • 代表所述存储的全局设置到专用类/模块

不,ruby不这样做。寻找红宝石用来解析名字的祖先链。

所以你将不得不使用Outer::BASE_DIR来代替。

here是一个关于ruby class系统和rails自动加载的好话题。

+0

试过这个。使用'puts Outer :: BASE_DIR'并得到这个错误(几乎相同):'':未初始化的常量Outer :: BASE_DIR(NameError)' – Chris911

+0

看看@ p11y的答案,问题是与文件的加载顺序有关。 ruby对文件和Ruby代码的加载顺序非常敏感。 – phoet