烦人的"警告:已经初始化的常量"消息的解决方案

63 ruby constants

今天我偶然发现了Ruby常量的棘手问题.在我们的团队中,有人创建了一个模块,该模块包含在多个模型中.在我们的(规范)测试输出中,这会产生警告消息,例如:

/home/ayrton/project/lib/life_cycle.rb:5:警告:已初始化常量RESET

解决这个问题的一种方法是,声明你的常量如下:

module LifeCycle

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

  #...
end
Run Code Online (Sandbox Code Playgroud)

我还阅读了一篇由Avdi Grimm撰写的博客文章,该文章提供了另一种解决方案,我想知道你对此事的看法.

Mat*_*ard 113

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

由于警告来自尝试重新分配具有相同值的常量,我只是改变了

module LifeCycle
  RESET = 'reset'
end
Run Code Online (Sandbox Code Playgroud)

module LifeCycle
  RESET ||= 'reset'
end
Run Code Online (Sandbox Code Playgroud)

这样可以处理警告,并且比检查是否定义了每个常量要简单得多.如果您找到更好的解决方案,请告诉我.

  • 如果警告是由您的类重新加载引起的,则Memoizing是一个很好的解决方案.如果你要覆盖第三方类的常量,那么保留警告就更安全了. (3认同)
  • 这非常整齐地处理警告. (2认同)

she*_*onh 20

这只是显式重新加载的应用程序中的问题,如Rails应用程序.

如果详细程度冒犯了你,你可以unless用作语句修饰符:

module LifeCycle
  RESET = 'reset' unless const_defined?(:RESET)
end
Run Code Online (Sandbox Code Playgroud)

这留下了一些反对Avdi仅使用方法的建议的弱论点:

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

如果你喜欢Avdi的建议足以忽略这些,那就去吧.

  • 如果问题是源重新加载,那么这会掩盖它。否则就解决了。:-) (2认同)

小智 5

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