From: "fxn (Xavier Noria)" <noreply@...>
Date: 2022-04-21T15:30:55+00:00
Subject: [ruby-core:108352] [Ruby master Bug#18622] const_get still looks in Object, while lexical constant lookup no longer does

Issue #18622 has been updated by fxn (Xavier Noria).


I you want to check only in the receiver, that is `mod.const_get(cname, false)` already.

If you want to check from the receiver up the ancestors chain, that is `mod.const_get(cname)` already.

If the receiver is a module, and the constant is not found in the ancestors the method checks `Object` manually as it happens in relative constant lookups. This is documented.

So, a relative constant lookup could be seen as checking the nesting + `const_get` + `const_missing`. This is how I see `const_get` and in that sense I am personally fine with the current behavior.

@Eregon opened this issue because for him, the manual check in `Object` is surprising (conceptually, regardless of documentation).

----------------------------------------
Bug #18622: const_get still looks in Object, while lexical constant lookup no longer does
https://bugs.ruby-lang.org/issues/18622#change-97378

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
There is some inconsistency here between literal constant lookup and the meta API (const_get).

Lexical constant lookup no longer uses a special case for Object, and this is good as it avoids surprises: #11547

However, `const_get` still looks in Object, even though that's confusing, inconsistent and IMHO shouldn't really happen.
```ruby
module ConstantSpecsTwo
  Foo = :cs_two_foo
end

module ConstantSpecs
end

p ConstantSpecs.const_get("ConstantSpecsTwo::Foo") # => :cs_two_foo
p ConstantSpecs::ConstantSpecsTwo::Foo # => const_get.rb:9:in `<main>': uninitialized constant ConstantSpecs::ConstantSpecsTwo (NameError)
```

I think we should change it so both behave the same (i.e., NameError).
It's like if `cd /foo/bar` would go to `/bar` if `/foo/bar` does not exist and `/bar` does.

`const_get` is a meta API so it cannot know the surrounding `Module.nesting`, but so I think it should consider the receiver of `const_get` as the only nesting (so just `ConstantSpecs` in this case, not `Object`).

Note this does not affect nested constants inside the `const_get` like `Foo` above (another way to look at the inconsistency that the first component is treated differently).

From https://bugs.ruby-lang.org/issues/11547#note-19



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>