Ruby 解决烦人问题的办法;警告:已初始化常数";消息

Ruby 解决烦人问题的办法;警告:已初始化常数";消息,ruby,constants,Ruby,Constants,今天我偶然发现了一个关于Ruby常量的棘手问题。在我们的团队中,有人创建了一个模块,该模块包含在多个模型中。在我们的(spec)测试中,将此结果输出为警告消息,例如: /home/ayrton/project/lib/life_cycle.rb:5:警告:已初始化 恒定复位 解决这个问题的一种方法是,像这样声明常量: module LifeCycle unless (const_defined?(:RESET)) RESET = 'reset' end #... end

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

/home/ayrton/project/lib/life_cycle.rb:5:警告:已初始化 恒定复位

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

module LifeCycle

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

  #...
end

我还读过一篇由Avdi Grimm撰写的博文,这篇博文提供了另一种选择,我想知道您对这件事的看法。

这只是在显式重新加载的应用程序(如Rails应用程序)中的一个问题

如果长篇大论冒犯了您,您可以使用
,除非
作为语句修饰符:

module LifeCycle
  RESET = 'reset' unless const_defined?(:RESET)
end
这就留下了一些反对Avdi只使用方法的微弱论据:

  • 常量查找比方法查找快
  • 常量值是在加载时定义的,而不是在(第一次)请求时定义的
  • 常数从视觉上表明它们不需要进行推导,并且

如果你喜欢Avdi的建议而忽略了这些,那就去吧。

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

由于警告来自尝试重新分配具有相同值的常量,因此我刚刚更改了

module LifeCycle
  RESET = 'reset'
end


这解决了警告问题,比检查是否定义了每个常量要简单得多。如果您找到了更好的解决方案,请告诉我。

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

您的意思是在多个模型中是
require
d,还是
include
d?即使
require
d多次,它也应该只加载一次。这实际上是一个Rails应用程序,我担心
除非定义了const\u?
是一个掩盖问题而不是实际解决问题的解决方案。如果问题是源代码重新加载,那么这就掩盖了它。否则,它将解决此问题。:-)这非常巧妙地处理了警告。如果警告是由于类被重新加载引起的,那么记忆是一个很好的解决方案。如果您正在重写第三方类中的常量,则更安全的做法是保留警告。这对Ruby有效,但Rubocop在执行此操作时抛出了一个错误:
在Style/MutableConstant cop检查时发生了一个错误
我忘记了这一点,但当您使用require\u Relative时,这是一个完美的解决方案。我正在运行“刀子客户列表”。我不知道或修改任何变量
module LifeCycle
  RESET ||= 'reset'
end