2011-10-31 21 views
48

今日、私はRubyの定数で厄介な問題に遭遇しました。私たちのチームでは、誰かが複数のモデルに含まれているモジュールを作成しました。迷惑な "警告:既に初期化された定数"メッセージへの解決

/home/ayrton/project/lib/life_cycle.rb:5:警告:私たち(スペック)テスト出力では、これは、次のような警告メッセージになり、すでに 定数RESET

つを初期化これを解決する方法は、あるこのようなあなたの定数を宣言することです:

module LifeCycle 

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

    #... 
end 

私も代替solutionを提供Avdiグリム、によって書かれ、ブログの記事を読んで、私はについては、あなたの意見があるかと思いましたこのm atter。

+0

.. Rubyでこのエラー変数名によるものであったのIntelliJ IDE .. が大文字で始まる宣言したときに...小文字にそれを作るには、この問題を解決します得たあなたはそれが 'require'dであることを意味します複数のモデルで、あるいは 'include'd?これは 'require'dを複数回実行しても1回だけロードする必要があります –

答えて

17

これは、Railsアプリケーションのように明示的にリロードするアプリケーションでのみ問題になります。

冗長性があなたを傷つける場合は、代わりの文修飾子としてunlessを使用することができます。

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

にのみ使用方法にAvdiの提案に対して、いくつかの弱いの引数を残し:

  • 定数のルックアップがあります
  • (最初の)リクエストではなく、一定の値がロード時に定義されます。
  • 定数visuallあなたが派生する仕事が必要でないことを示唆しています。

これらを無視するのに十分な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は大文字変数が定数であると考えるので、定数が変更されたことを警告するエラーが表示されます。

関連する問題