Feature #16644
closed
qualified const init (self::CONST1 = 1) should be allowed in methods
Added by bughit (bug hit) about 4 years ago.
Updated about 4 years ago.
Description
module Mod1
def self.define_consts
const_set(:CONST1, :CONST1)
# this is actual const re-assignment but only a warning
const_set(:CONST1, :CONST1)
# this is const initialization but becomes an error
# because it looks like it could be re-assignment
# if actual const re-assignment is only a warning
# why is a possible const re-assignment (which might not be one), an error
self::CONST2 = :CONST2 unless const_defined?(:CONST2, false)
end
define_consts
end
- Backport deleted (
2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
- Tracker changed from Bug to Misc
- ruby -v deleted (
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux])
These are two different things. Ruby always warns for assigning to an existing constant, regardless of using const_set
or CONST = ...
. It does not support using CONST = ...
inside a method, though const_set
is allowed. Similarly, you can use Class.new
and Module.new
to define classes and modules in method bodies, but you can't use the class
or module
keywords directly in method bodies.
This behavior exists at least back to 1.8, and probably before that. I'm fairly sure this is the expected behavior. If you would like the behavior changed, please submit a feature request.
I realize this does not directly answer the question in the issue subject. I'm switching this to the Misc tracker, since this is not a bug report.
- Tracker changed from Misc to Feature
- Subject changed from why is potential dynamic constant assignment an error when actual dynamic constant assignment is only a warning to qualified const init (self::CONST1 = 1) should be allowed in methods
a qualified const init is so similar to meta-programming const_set
that there's no reason to block it
module Mod1
end
def define_consts(mod)
# since this allowed
mod.const_set(:CONST1, :CONST1) unless mod.const_defined?(:CONST1, false)
# this should be too
mod::CONST2 = :CONST2 unless mod.const_defined?(:CONST2, false)
end
define_consts(Mod1)
Use const_set
. I'd rather make all const re-assignment error if compatibility does not matter.
Matz.
- Status changed from Open to Rejected
I'd rather make all const re-assignment error
I don't disagree, actual const re-assignment, dynamically detected, probably should be an error. But then especially, there is no reason that a qualified const initialization (mod::CONST2 = :CONST2 unless mod.const_defined?(:CONST2, false)
) should be an error. You would already be protected from const re-assignment, so why block what is simply a more direct syntax for initializing a const from a macro method?
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0