I do not like the way Ruby does its constant name resolution.
Suppose somewhere in your codebase you define a module Parent
:
module Parent
FOO = "foo"
end
And some other place, you add a method onto a module inside Parent
called Child
:
module Parent
module Child
def self.nested_wut
puts self.object_id
FOO
end
end
end
And somewhere else you add yet another method onto Parent
's Child
, this time using a different syntax:
module Parent::Child
def self.fully_qualified_wut
puts self.object_id
FOO
end
end
To my thinking, these two _wut
methods should work exactly the same way. But they don't:
> Parent::Child.nested_wut
4836
=> "foo"
> Parent::Child.fully_qualified_wut
4836
NameError: Missing or uninitialized constant: Parent::Child::Foo
from ...
(printing the object_id
in there to demonstrate that this is only a lexical difference)
Am I crazy for thinking that it's much less obvious to have constant name resolution be lexically scoped?
My strongest real-world reason for loathing this is that with lexical scoping, there are practical reasons that I should avoid using
module A::B::C::D
# ...
end
And should instead use
module AlphaArgyle
module BetaMaximum
module GammaRaysOnManInTheMoonMarigolds
module DotingFather
# ...
end
end
end
end
Which is an unforgiveable waste of space, both vertical and horizontal. Starting almost every line with eight spaces just so that I can avoid having to use fully qualified names any time I might want to access a constant further up the module hierarchy (e.g. AlphaArgyle::BetaMaximum::GammaRaysOnManInTheMoonMarigolds::POTENCY
) is silly. I want my code as close to the left margin as possible—this increases legibility as it makes it much easier to judge by eye what a particular end
lines up with.
Nonsense.