From: "alexeymuranov (Alexey Muranov)" Date: 2012-07-29T04:24:48+09:00 Subject: [ruby-core:46840] [ruby-trunk - Bug #6810] `module A::B; end` is not equivalent to `module A; module B; end; end` with respect to constant lookup (scope) Issue #6810 has been updated by alexeymuranov (Alexey Muranov). fxn (Xavier Noria) wrote: > Yes, this is expected. > > The resolution algorithm first checks the modules in the nesting (in their very constants table, it ignores their ancestors), then the ancestors of the module the constants appears in (the first one in the nesting, or Object if the nesting is empty), and if the former is a module, then Object is checked by hand (and it still tries const_missing if all fails). > > The key to understand those examples, in addition to the algorithm, is to be aware of the respective nestings: > > module A > module B > Module.nesting # => [A::B, A] > end > end > > whereas > > module A::B > Module.nesting # => [A::B] > end > > In the second case A is not checked, since it is not in the nesting, it is not an ancestor of A::B, and it is not Object. > > The nesting is only modified by the class and module keywords, and by opening a singleton class with class << object (and some other obscure cases related to string eval'ing). In particular, the nesting inside and outside class methods defined with def self... is the same. Xavier, thanks for the explanation, i see now why it works this way, so this is not a bug. However, can anybody please explain to me why this is a desired behavior, i mean the way the nesting is calculated? Wouldn't it be easier if module A; end module A::B; # do something end was equivalent to module A module B # do something end end ? ---------------------------------------- Bug #6810: `module A::B; end` is not equivalent to `module A; module B; end; end` with respect to constant lookup (scope) https://bugs.ruby-lang.org/issues/6810#change-28513 Author: alexeymuranov (Alexey Muranov) Status: Open Priority: Normal Assignee: Category: core Target version: ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin10.8.0] =begin Is this the expected behavior? To me it is rather surprising: N = 0 module A module B def self.f; N; end end N = 1 end A::B.f # => 1 but N = 0 module A; end module A::B def self.f; N; end end module A N = 1 end A::B.f # => 0 Even more striking: module A module B def self.f; N; end end end N = 0 A::B.f # => 0 A::N = 1 puts A::B.f # => 1 A::B::N = 2 A::B.f # => 2 but module A; end module A::B def self.f; N; end end N = 0 A::B.f # => 0 A::N = 1 A::B.f # => 0 A::B::N = 2 A::B.f # => 2 =end -- http://bugs.ruby-lang.org/