-
-
Save stevenharman/1211552 to your computer and use it in GitHub Desktop.
module Foo | |
end | |
module Foo::Bar | |
end | |
class Baz | |
end | |
class Quux | |
end | |
class Foo::Bar::Base | |
end | |
# a class that inherits from a base | |
class Foo::Bar::Baz < Foo::Bar::Base | |
def a_method | |
puts Baz | |
end | |
end | |
# a class that mixes the "base stuff" in | |
class Foo::Bar::Quux | |
include Foo::Bar | |
def a_method | |
puts Quux | |
end | |
end | |
puts "a new Foo::Bar::Baz, Baz => " | |
f = Foo::Bar::Baz.new | |
f.a_method #=> Baz | |
puts "a new Foo::Bar::Quux, Quux => " | |
q = Foo::Bar::Quux.new | |
q.a_method #=> Foo::Bar::Quux |
@derickbailey I think its the mixing in of the Foo::Bar
module that is causing the change in how Quux
is resolved inside Foo::Bar::Quux#a_method
.
Including a module inserts that module in the class hierarchy, and so lookups for constants in that module (i.e. Foo::Bar::Quux
) are found in the included module, and Ruby stops moving up the chain, thus never making it to the main Object::Quux
constant that we really wanted.
Does that make any sense?
ah - i didn't notice that second Baz class... your thinking on the lines of the module sounds correct. since a module is injected into the inheritance hierarchy, it makes sense that the code would move up that hierarchy to see if it can find a reference to the Quux / Baz class in the hierarchy, first. if not, then it looks back to the root namespace...
of course, i've seen situations where this kind of gets tossed upside down, but i think those are edge cases caused by duplicating module and class names in different namespaces. :P
@derickbailey Actually, there are two
Baz
classes, one at the main scope and one within theFoo::Bar
module.I understand using the scope operator to say, "give me the one from the main scope" via
::Bar
or::Quux
. What I don't understand is whyFoo::Bar::Baz#a_method
resolvesBaz
to be::Baz
butFoo::Bar::Quux#a_method
(which mixedFoo::Bar
in) resolvesQuux
to beFoo::Bar::Quux
WTF? :)