Project

General

Profile

Bug #10488

Consistency of Module#const_defined? and constant lookup

Added by Eregon (Benoit Daloze) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
ruby -v:
ruby 2.2.0dev (2014-10-12 trunk 47890) [x86_64-darwin13]
Backport:
[ruby-core:66145]

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 in Object and its ancestors, but constant access (::) will not look in Object or above.

    Enumerable.const_defined? :String
    Enumerable::String #=> NameError: uninitialized constant Enumerable::String
    
  • if Const is private, const_defined? will return true while mod::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) over 5 years ago

  • Description updated (diff)

Benoit Daloze wrote:

  • if mod is a Module but not a class, const_defined? will look in Object and its ancestors, but constant access (::) will not look in Object or above.

mod.const_defined?(:Const, false) behaves like as mod::Const.

  • if Const is private, const_defined? will return true while mod::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) over 5 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) over 5 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.

Also available in: Atom PDF