Bug #10488
closedConsistency of Module#const_defined? and constant lookup
Description
Currently, if for some module mod
and constant Const
,
mod.const_defined?(:Const)
is true does not imply mod::Const
is not an error.
This is inconsistent for at least the following cases:
-
if mod is a Module but not a class,
const_defined?
will look inObject
and its ancestors, but constant access (::) will not look inObject
or above.Enumerable.const_defined? :String Enumerable::String #=> NameError: uninitialized constant Enumerable::String
-
if
Const
is private,const_defined?
will return true whilemod::Const
will raise an error.C = 42 Object.private_constant :C String.const_defined? :C #=> true String::C #=> NameError: private constant String::C referenced # This works, but is due to the lexical scope lookup class String C #=> 42 end
Is this intended?
Should it not mirror the behavior of defined?(mod::Const)
?
Or the behavior of method_defined?
Updated by nobu (Nobuyoshi Nakada) about 10 years ago
- Description updated (diff)
Benoit Daloze wrote:
- if mod is a Module but not a class,
const_defined?
will look inObject
and its ancestors, but constant access (::) will not look inObject
or above.
mod.const_defined?(:Const, false)
behaves like as mod::Const
.
- if
Const
is private,const_defined?
will return true whilemod::Const
will raise an error.
Since const_defined?
is a method, it can't know the caller's context.
Or the behavior of
method_defined?
Yes, it is a similar case.
Updated by fxn (Xavier Noria) about 10 years ago
Regarding the first point, here const_defined?
is consistent with const_get
:
X = 1
Module.new.const_get(:X) #=> 1
In general the constants API seems to be "closer" to the algorithm that resolves constant names than the one for constant paths.
However, if I got true from const_defined?
I would expect to be able to access the constant in the next line so to speak. This is not guaranteed nowadays... in my view it would be more coherent to autoload.
Updated by Eregon (Benoit Daloze) about 10 years ago
- Status changed from Open to Closed
Indeed, it looks consistent with const_get
and it seems difficult to be more consistent while keeping the same API.
Let's close this then.