2011-10-31 86 views
48

今天我偶然发现了一个棘手的问题,用Ruby常量。在我们的团队中,有人创建了一个模块,该模块包含在多个模型中。在我们的(规范)测试输出这导致到警告信息,如:解决恼人的“警告:已经初始化常量”消息

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

一的方式来解决这个问题是,正在申报的常数是这样的:

module LifeCycle 

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

    #... 
end 

我也看到了一篇博客文章,通过Avdi格林,它提供了一种替代solution写的,我想知道你的意见是什么,关于这米东北黑钙土。

+0

你的意思是'require'd在多个模型中,还是'include'd?它应该只加载一次,即使'require'd多次 –

回答

17

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

如果冗长冒犯了你,你可以使用unless作为语句修改代替:

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

这使得一些轻微的理由反对Avdi的建议,只使用方法:

  • 不断查找是快于方法查找,
  • 恒定值在负载上定义,而不是(第一个)请求,
  • 常量visuall y建议他们不需要任何工作来推导,并且

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

+0

这实际上是一个Rails应用程序,我担心'除非const_defined?'是一个解决方案,它掩盖了问题并没有真正解决它。 – Ayrton

+1

如果问题是源重装,那么这会掩盖它。否则,它解决了它。:-) – sheldonh

81

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

由于警告是试图重新分配恒定,其值相同,我只是改变

module LifeCycle 
    RESET = 'reset' 
end 

module LifeCycle 
    RESET ||= 'reset' 
end 

这花了警告的关怀和比检查简单得多如果每个常量都被定义。让我知道你是否找到更好的解决方案。

+2

这非常整洁地处理警告。 –

+2

如果警告是由您的课程重新加载引起的,则记忆是一个很好的解决方案。如果您从第三方课程中覆盖常量,则保留警告是比较安全的。 –

+0

这适用于Ruby,但Rubocop在执行此操作时会抛出一个错误:'Style/MutableConstant警察正在检查时发生错误' – anthony

6

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

0

我在Ruby中得到这个错误时的IntelliJ IDE .. 这是由于变量名声明开始用大写..作出这样的小写会解决这个问题..