Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Created September 12, 2011 15:29
Show Gist options
  • Save stevenharman/1211552 to your computer and use it in GitHub Desktop.
Save stevenharman/1211552 to your computer and use it in GitHub Desktop.
Constant scoping weirdness in Ruby...
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
@stevenharman
Copy link
Author

@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?

@mxriverlynn
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment