ruby 烦人的“警告:已初始化常量”消息的解决方案
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7953611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
solutions to the annoying "warning: already initialized constant" message
提问by Matthew Leonard
Today I've stumbled upon a tricky issue with Ruby constants. In our team someone created a module, which is included into multiple models. In our (spec) test output this results into warning messages such as:
今天我偶然发现了一个关于 Ruby 常量的棘手问题。在我们的团队中,有人创建了一个模块,该模块包含在多个模型中。在我们的(规范)测试输出中,这会导致警告消息,例如:
/home/ayrton/project/lib/life_cycle.rb:5: warning: already initialized constant RESET
/home/ayrton/project/lib/life_cycle.rb:5: 警告:已初始化常量 RESET
One way to solve this is, is to declare your constants like this:
解决这个问题的一种方法是,像这样声明你的常量:
module LifeCycle
unless (const_defined?(:RESET))
RESET = 'reset'
end
#...
end
I've also read a blog post, written by Avdi Grimm, which provides an alternative solution, I was wondering what your opinions are, regarding this matter.
我还阅读了 Avdi Grimm 撰写的博客文章,该文章提供了另一种解决方案,我想知道您对此有何看法。
回答by Matthew Leonard
I encountered this same problem today and found a simple solution.
我今天遇到了同样的问题,并找到了一个简单的解决方案。
Since the warning is from trying to reassign a constant with its same value, I just changed
由于警告来自尝试重新分配具有相同值的常量,因此我只是更改了
module LifeCycle
RESET = 'reset'
end
to
到
module LifeCycle
RESET ||= 'reset'
end
This took care of the warning and is a lot simpler than checking if each constant is defined. Let me know if you find a better solution.
这会处理警告,并且比检查每个常量是否已定义要简单得多。如果您找到更好的解决方案,请告诉我。
回答by sheldonh
This is only a problem in applications that explicitly reload, like Rails applications.
这只是显式重新加载的应用程序中的问题,例如 Rails 应用程序。
If the verbosity offends you, you can use unlessas a statement modifier instead:
如果冗长冒犯了您,您可以将其unless用作语句修饰符:
module LifeCycle
RESET = 'reset' unless const_defined?(:RESET)
end
This leaves a few weak arguments against Avdi's suggestion to only use methods:
这留下了一些反对 Avdi 建议只使用方法的弱论点:
- constant lookup is faster than method lookup,
- constant values are defined on load, not on (first) request,
- constants visually suggest that they require no work to derive, and
- 常量查找比方法查找快,
- 常量值是在加载时定义的,而不是(第一个)请求时,
- 常量在视觉上表明它们不需要工作来推导,并且
If you like Avdi's suggestion enough to ignore these, go with it.
如果你喜欢 Avdi 的建议足以忽略这些,那就去吧。
回答by Luis Pizana
RESET is not a constant if it keeps changing in your code. If you rename it to lower case 'reset', the problem disappears. Ruby thinks Upper case variables are constants and thus displays an error to warn you that a constant has changed.
如果 RESET 在您的代码中不断变化,则它不是常量。如果您将其重命名为小写的“reset”,问题就会消失。Ruby 认为大写变量是常量,因此会显示错误以警告您常量已更改。

