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 inObjectand its ancestors, but constant access (::) will not look inObjector above.Enumerable.const_defined? :String Enumerable::String #=> NameError: uninitialized constant Enumerable::String
- 
if Constis private,const_defined?will return true whilemod::Constwill 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) almost 11 years ago
          Updated by nobu (Nobuyoshi Nakada) almost 11 years ago
          
          
        
        
      
      - Description updated (diff)
Benoit Daloze wrote:
- if mod is a Module but not a class,
const_defined?will look inObjectand its ancestors, but constant access (::) will not look inObjector above.
mod.const_defined?(:Const, false) behaves like as mod::Const.
- if
Constis private,const_defined?will return true whilemod::Constwill 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) almost 11 years ago
          Updated by fxn (Xavier Noria) almost 11 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) almost 11 years ago
          Updated by Eregon (Benoit Daloze) almost 11 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.