Issue #10702 has been updated by Kelly Stannard.


I think that it should be found in the lexical lookup. Let me try explaining this again. My understanding of getting nested constants is that if I were to do this:

~~~
module X
  module Y; end

  module Z
    Y
  end
end
~~~

Then ruby will do this:

check X::Z for the const Y
check X for the const Y
X::Y is found in X

My confusion comes from how include interacts with the lookup chain. For example:

~~~
module A; module B; end; end

module X
  include A
end

puts X::B # => A::B

module X
  puts B # => A::B
end
~~~

This implies that B is now part of the lexical scope of X and points at the const A::B. This makes sense to me. The part that breaks the logical flow is that despite B being seemingly in the lexical scope of X at this point, any attempt to access B from within a module that is inside of X's lexical scope fails.

~~~
module A; module B; end; end

module X
  include A
end

puts X::B # => A::B

module X
  puts B # => A::B

  module Y
    puts B # => NameError: uninitialized constant X::Y::B
  end
end
~~~

So if I understand correctly, ruby does this, what i believe to be erroneous, lookup:

check X::Y for B
check X for B
check :: for B
fail

If X::B is not in the lexical lookup chain, then how is it being found anywhere?


----------------------------------------
Bug #10702: Constant look up inconsistency with constants defined in included modules
https://bugs.ruby-lang.org/issues/10702#change-52157

* Author: Kelly Stannard
* Status: Rejected
* Priority: Normal
* Assignee: 
* ruby -v: 2.2-head
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
https://gist.github.com/kwstannard/c0f722976ba023cc5755

```ruby
module A
  module B
  end
end

module C
  include A

  puts B.inspect # => A::B

  class D
    puts B.inspect rescue puts 'failed' # => failed
  end

  B = B

  class E
    puts B.inspect # => A::B
  end
end
```

When you include a module you gain access to that module's constants as seen in line 9. Line 19 shows that you can get constants defined in the nested module when the constant is defined within the module itself.

Line 12 is the bug. Shouldn't class `D` be able to access module `B` since the previous line shows that module `C` has access to Module `B`?



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