Ori*_*all 2 ruby inheritance ruby-on-rails constants autoload
错误类似于NameError: uninitialized constant Foo::Bar(whenBar不是 的后代Foo)。
我知道它与加载(自动加载?)常量有关,并且我觉得其中的任何内容都lib/可以安全地不加前缀,::因为它是自动加载的(或其他东西)。
刚刚发生在我身上的一个例子是这样的:
应用程序/资产/类/base_class.rb
class BaseClass
end
Run Code Online (Sandbox Code Playgroud)
应用程序/资产/some_module/some_class.rb
module SomeModule
class SomeClass < BaseClass
end
end
Run Code Online (Sandbox Code Playgroud)
我正在运行规范并收到“加载[文件]时发生错误”:NameError: uninitialized constant SomeModule::SomeClass::BaseClass。
现在,我知道它正在尝试BaseClass在SomeModule::SomeClass. 但这在几个小时前还在工作,然后在没有对这些文件进行任何更改后停止了。
所以,我可以直接加上 a::并与 一起使用class SomeClass < ::BaseClass,但不明白为什么感觉很糟糕,然后我想,我是否需要一直在我的所有代码中添加胡椒粉::?
什么时候需要在 Ruby 常量前添加“::”前缀?
当你引用一个常量时,Ruby 会在当前模块嵌套中查找它。
module SomeModule
puts Module.nesting.inspect # the current module nesting is [SomeModule]
end
Run Code Online (Sandbox Code Playgroud)
模块嵌套主要通过使用module和设置class关键字打开类/模块来设置。
如果在那里没有找到它,它将在模块嵌套中继续向上,直到到达 main,如果到那时仍然没有找到常量,那么您将得到一个丢失常量的错误。
此错误可能会有些令人困惑,因为该消息包含开始查找常量的模块嵌套。
通过在常量前面加上前缀,::您可以显式地告诉 Ruby 从顶级命名空间解析该常量:
module Bar
def self.hello
puts "Hello from the top level Bar"
end
end
module Foo
module Bar
def self.hello
puts "Hello from Foo::Bar"
end
end
def self.test
Bar.hello # the current module nesting is Foo.
::Bar.hello
end
end
Foo.test
# Will output:
# Hello from Foo::Bar
# Hello from the top level Bar
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这并不是严格必要的,但显式引用您自己的命名空间(依赖项)之外的常量是一个很好的做法。
那么为什么我的代码停止工作了?
如果没有实际的可复制示例,几乎不可能判断。它可能是“与程序员相关的问题”(您搞砸了并移动/删除/重命名了文件),也可能与使用中的自动加载器的问题有关。由于其猴子补丁的方式,经典的自动加载器更容易出现错误行为Object#constant_missing。
| 归档时间: |
|
| 查看次数: |
868 次 |
| 最近记录: |