【问题标题】:solutions to the annoying "warning: already initialized constant" message烦人的“警告:已初始化常量”消息的解决方案
【发布时间】:2011-12-18 17:03:44
【问题描述】:

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

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

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

module LifeCycle

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

  #...
end

我还阅读了 Avdi Grimm 撰写的博客文章,其中提供了替代方案 solution,我想知道您对此事有何看法。

【问题讨论】:

  • 你的意思是在多个模型中是required,还是included?即使required 多次也应该只加载一次

标签: ruby constants


【解决方案1】:

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

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

module LifeCycle
  RESET = 'reset'
end

module LifeCycle
  RESET ||= 'reset'
end

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

【讨论】:

  • 这非常巧妙地处理了警告。
  • 如果警告是由你的类被重新加载引起的,那么记忆是一个很好的解决方案。如果您要覆盖来自 3rd-party 类的常量,则将警告留在原处会更安全。
  • 这适用于 Ruby,但 Rubocop 在这样做时会抛出错误:An error occurred while Style/MutableConstant cop was inspecting <file>
  • 我忘了这个,但是当你使用 require_relative 时它是完美的解决方案
【解决方案2】:

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

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

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

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

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

如果您喜欢 Avdi 的建议而足以忽略这些,那就去吧。

【讨论】:

  • 这实际上是一个Rails应用程序,我担心unless const_defined?是一个掩盖问题而不是真正解决问题的解决方案。
  • 如果问题是源重新加载,那么这会掩盖它。否则,它会解决它。 :-)
【解决方案3】:

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

【讨论】:

  • 我只是在运行“刀客户列表”。我不知道或修改任何变量
猜你喜欢
  • 2011-08-29
  • 2013-09-24
  • 1970-01-01
  • 2015-08-08
  • 2014-07-25
  • 2021-07-04
  • 2011-01-02
  • 2011-11-29
  • 1970-01-01
相关资源
最近更新 更多