solutions to the annoying "warning: already initialized constant" message

RubyConstants

Ruby Problem Overview


Today I've stumbled upon a tricky issue with Ruby constants. In our team someone created a module, which is included into multiple models. In our (spec) test output this results into warning messages such as:

> /home/ayrton/project/lib/life_cycle.rb:5: warning: already initialized > constant RESET

One way to solve this is, is to declare your constants like this:

module LifeCycle

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

  #...
end

I've also read a blog post, written by Avdi Grimm, which provides an alternative solution, I was wondering what your opinions are, regarding this matter.

Ruby Solutions


Solution 1 - Ruby

I encountered this same problem today and found a simple solution.

Since the warning is from trying to reassign a constant with its same value, I just changed

module LifeCycle
  RESET = 'reset'
end

to

module LifeCycle
  RESET ||= 'reset'
end

This took care of the warning and is a lot simpler than checking if each constant is defined. Let me know if you find a better solution.

Solution 2 - Ruby

This is only a problem in applications that explicitly reload, like Rails applications.

If the verbosity offends you, you can use unless as a statement modifier instead:

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

This leaves a few weak arguments against Avdi's suggestion to only use methods:

  • constant lookup is faster than method lookup,
  • constant values are defined on load, not on (first) request,
  • constants visually suggest that they require no work to derive, and

If you like Avdi's suggestion enough to ignore these, go with it.

Solution 3 - Ruby

RESET is not a constant if it keeps changing in your code. If you rename it to lower case 'reset', the problem disappears. Ruby thinks Upper case variables are constants and thus displays an error to warn you that a constant has changed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser191766View Question on Stackoverflow
Solution 1 - RubyMatthew LeonardView Answer on Stackoverflow
Solution 2 - RubysheldonhView Answer on Stackoverflow
Solution 3 - RubyLuis PizanaView Answer on Stackoverflow