I can’t for the life of me figure out why the following code makes Ruby
puke when I try to execute it:
module Rlang
module Error
class RlangException < Exception ; end
end
module Utility
def e8(value) ; [value].pack('C') ; end
end
module External
include Rlang::Error
include Rlang::Utility
TAG_CACHED_ATOM = e8(67)
end
end
The precise error I get is “junk.rb:11: undefined method `e8’ for
Rlang::External:Module (NoMethodError)” which is the line with
“TAG_CACHED_ATOM = …” in it. I’ve tried the following changes with
the following results:
1. Completely specify e8 by using "Rlang::Utility.e8" or
"Rlang::Utility::e8". This produces no change to the message
whatsoever.
2. Renaming bits and pieces under the assumption that I've got a
naming clash with something deep. This only changes the name of
the method it claims to not be able to find.
3. Moving the definition of e8 to be in the External module. This
is where brain damage sets in as the message doesn't change in
the slightest. (I am well and truly baffled by this stage.)
4. Moving the definition of e8 to be in the Rlang module. This
results in, you guessed it!, no change to the message at all.
5. Moving the definition of e8 to be outside of any module at all.
This results in ... it works.
#5 is a solution but it is a truly suboptimal one in my opinion. I do
not want to clutter up the global namespace of my clients with cryptic
little utility functions (in the real code there’s about a dozen of
these). So while I could live with #5, I would rather not if there was
a better way to do this. Something deep about Ruby’s module system is
eluding me here, I think, and I’d rather understand it than just cover
it over and inconvenience my clients’ coding in the process.