解决恼人的“警告: 已经初始化常量”消息

今天我偶然发现了 Ruby 常量的一个棘手问题。在我们的团队中,有人创建了一个包含在多个模型中的模块。在我们的(spec)测试输出中,这个结果会变成警告消息,比如:

/home/ayrton/project/lib/life _ Cycle. rb: 5: 警告: 已初始化 常数重置

解决这个问题的一个方法是,像这样声明你的常量:

module LifeCycle


unless (const_defined?(:RESET))
RESET = 'reset'
end


#...
end

我也读过一篇由 Avdi Grimm 撰写的博文,它提供了另一种 解决方案,我想知道你对此事有什么看法。

57959 次浏览

这只是在显式重载的应用程序(如 Rails 应用程序)中才会出现的问题。

如果冗长冒犯了您,您可以使用 unless作为语句修饰语:

module LifeCycle
RESET = 'reset' unless const_defined?(:RESET)
end

这就留下了一些反对 Avdi 建议只使用方法的微弱论据:

  • 常量查找比方法查找快,
  • 常量值是在加载时定义的,而不是在(第一次)请求时定义的,
  • 常数在视觉上表明它们不需要任何工作就可以推导出来,而且

如果你喜欢阿夫迪的建议,足以忽略这些,去吧。

我今天遇到了同样的问题,并找到了一个简单的解决方案。

由于这个警告来自于尝试重新分配一个具有相同值的常数,所以我只是更改了

module LifeCycle
RESET = 'reset'
end

module LifeCycle
RESET ||= 'reset'
end

这样就解决了警告问题,而且比检查是否定义了每个常量要简单得多。如果你找到更好的解决办法,请告诉我。

如果重置在代码中不断更改,则重置不是常量。如果您将其重命名为小写的“重置”,问题就会消失。Ruby 认为 Upper case 变量是常量,因此会显示一个错误来警告您某个常量已经更改。