It was my understanding that consts are first searched for in their
own module scope before Ruby starts looking elsewhere. So, if you have
a class called X in a module M1::M2 and another one at top level, and
you’re inside M1::M2, then referencing X gets you M1::M2::X.
This doesn’t appear to be the case though:
ruby-1.9.2-p0 :001 > module Foo; end
=> nil
ruby-1.9.2-p0 :002 > module Foo::Bar; class Baz; end; end
=> nil
ruby-1.9.2-p0 :003 > class Baz; def say; “::Baz”; end; end
=> nil
ruby-1.9.2-p0 :004 > class Foo::Bar::Baz; def say; “::Foo::Bar::Baz”;
end; def x; Baz.new.say; end; end
=> nil
Yeah. Ruby first tries to find the constant in the “lexical scope” of
the reference - immediately enclosing module/class, then the next
enclosing module/class, and so on.
You can find out the modules/classes that are searched by calling
Module.nesting method at that point.
class Foo::Bar::Baz; def say; “::Foo::Bar::Baz”;
end; def x; Baz.new.say; end; end
Foo::Bar::Baz.new.x
Here, Baz is first looked up in Foo::Bar::Baz, and then the global
namespace; confirm with Module.nesting. Ruby finds Baz in the later,
so '::Baz is the expected output.
module Foo::Bar
class Baz
def say; “::Foo::Bar::Baz”; end
def x; Baz.new.say; end
end
end
Foo::Bar::Baz.new.x #=> “::Foo::Bar::Baz”
Here, Ruby first looks up Baz in Foo::Bar::Baz, followed by Foo::Bar
finds, and then the global namespace. Again, you can confirm this with
Module.nesting.
Sometime back, I had answered a similar question. You might want to
have a look1.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.