我有一个Rails模型:app/models/A.rb
- &gt; class A < ActiveRecord::Base
然后我有:app/services/a/b/c.rb
- &gt; class A::B::C
,其中a
和b
都是文件夹。 AFAIK,app/<foldername>
是自动加载的,所以这不是问题。
最后,我有一个模块:module B
(它是一个带有此名称的外部宝石)。
如果我尝试这样做:A::B::C.new
它会抛出一条错误消息:toplevel constant ... referenced by ...
(不记得确切) - 换句话说,它确实不工作。
a
文件夹下定义的其他类 - 工作正常。例如:app/services/a/x.rb
(class A::X
)
如果我尝试A::B
,我只需转到B
(宝石),并发出警告信息(但它会继续有效)。
但是,如果我重命名a
或b
文件夹名称(当然还有类签名) - 它的工作正常!
所以,
1)为什么? ruby如何处理所有这些类,模块,命名空间和包含?
2)是否有可能让一切工作无需重命名?
提前致谢!
答案 0 :(得分:1)
您可能需要在a/b.rb
中声明的中间A :: B才能在引用之前正确定义模块A::B
,或者您可以在最终文件中重新设置声明样式。
例如:
# a/b/c.rb
class A::B::C
end
这取决于模块或类A和A :: B在加载文件之前定义。
你可以这样做:
class A
module B
class C
end
end
end
这将强制声明所有中间体。由于这引入了很多缩进,一种稍微不那么混乱的方法是:
class A
module B
end
end
class A::B::C
end
当然,让a.rb
和a/b.rb
具有适当的中间声明通常有助于避免所有这些。