Is there a way to disable warning: already initialized constant
when loading particular files?

- 165,429
- 45
- 277
- 381
-
4Is fixing the code really out of the question? – sarnold Feb 10 '12 at 23:27
-
1Warnings are often indicative of non-fatal **errors**, and should be fixed. In this case you do very possibly have a real problem that should be fixed. – Andrew Marshall Feb 10 '12 at 23:29
-
2you initialized your variable more than once. – Dmitry Savy Feb 10 '12 at 23:34
-
3@DmitrySavy Yes. That's right. But that does not answer my question. – sawa Feb 10 '12 at 23:35
-
1possible duplicate of [How to redefine a Ruby constant without warning?](http://stackoverflow.com/questions/3375360/how-to-redefine-a-ruby-constant-without-warning) – the Tin Man Feb 10 '12 at 23:36
-
@theTinMan Thanks. I think your link tells my what I need to do. But still, I would like to do it without using special methods mentioned there. – sawa Feb 10 '12 at 23:40
5 Answers
The solution to your problem depends on what is causing it.
1 - You are changing the value of a constant that was set before somewhere in your code, or are trying to define a constant with the same name as an existant class or module. Solution: don't use constants if you know in advance that the value of the constant will change; don't define constants with the same name as class/modules.
2 - You are in a situation where you want to redefine a constant for good reasons, without getting warnings. There are two options.
First, you could undefine the constant before redefining it (this requires a helper method, because remove_const
is a private function):
Object.module_eval do
# Unset a constant without private access.
def self.const_unset(const)
self.instance_eval { remove_const(const) }
end
end
Or, you could just tell the Ruby interpreter to shut up (this suppresses all warnings):
# Runs a block of code without warnings.
def silence_warnings(&block)
warn_level = $VERBOSE
$VERBOSE = nil
result = block.call
$VERBOSE = warn_level
result
end
3 - You are requiring an external library that defines a class/module whose name clashes with a new constant or class/module you are creating. Solution: wrap your code inside a top-level module-namespace to prevent the name clash.
class SomeClass; end
module SomeModule
SomeClass = '...'
end
4 - Same as above, but you absolutely need to define a class with the same name as the gem/library's class. Solution: you can assign the library's class name to a variable, and then clear it for your later use:
require 'clashing_library'
some_class_alias = SomeClass
SomeClass = nil
# You can now define your own class:
class SomeClass; end
# Or your own constant:
SomeClass = 'foo'

- 6,699
- 8
- 48
- 80
Try this :
Kernel::silence_warnings { MY_CONSTANT = 'my value '}

- 428
- 5
- 4
-
4
-
9It's a part of rails: http://api.rubyonrails.org/classes/Kernel.html#method-i-silence_warnings – stackdump Apr 18 '14 at 00:38
-
2Excellent solution, It's part of rails, but you can just import the 2 methods `silence_warnings` and `with_warnings` in a file of your choice and patch `Kernel` with it. – Benjamin Bouchet Feb 08 '15 at 01:32
-
2
-
And you can use it without `Kernel::` prefix, it'll be even shorter then! – Lev Lukomsky Jul 13 '18 at 08:31
To suppress warnings, use the following code at the top of the script:
$VERBOSE = nil
-
1This one is the most useful for other people in the broader context, because Constant redefinition is only one thing that can trigger non-fatal compilation warnings. It's all very well suggesting you fix your code, but that presumes the thing triggering this is in your code and not something in an upstream library. – Stuart Harland Jul 31 '19 at 09:44
-
yes, that works, but silencing *all* warnings is maybe not the best in production – Tilo Jan 12 '22 at 21:54
The accepted answer to this question was helpful. I looked at the Rails source to get the following. Before and after loading the file, I can insert these lines:
# Supress warning messages.
original_verbose, $VERBOSE = $VERBOSE, nil
load(file_in_question)
# Activate warning messages again.
$VERBOSE = original_verbose
Using user2398029's reply the simplest way for me to remove warnings was to add this line:
before { described_class.instance_eval { remove_const(:CONSTANT_NAME) } }

- 1,047
- 11
- 26