# 13 lines of confusion

**URL:** <https://www.ruby-forum.com/t/13-lines-of-confusion/138212>\
**Category:** Ruby\
**Created:** [May 21, 2008, 4:03am UTC](https://www.ruby-forum.com/t/13-lines-of-confusion/138212 "2008-05-21T04:03:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_TSRichter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@Michael\_TSRichter](https://www.ruby-forum.com/u/Michael_TSRichter)\
**Post date:** [May 21, 2008, 4:03am UTC](https://www.ruby-forum.com/t/13-lines-of-confusion/138212/1 "2008-05-21T04:03:42Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Michael\_TSRichter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@Michael\_TSRichter](https://www.ruby-forum.com/u/Michael_TSRichter)\
**Post date:** [May 21, 2008, 4:20am UTC](https://www.ruby-forum.com/t/13-lines-of-confusion/138212/2 "2008-05-21T04:20:05Z")

</div>

Oops. Forgot to mention: I’ve also tried putting each module into a  
separate file which is then required. Same result.

---

<div class="post-metadata">

**Author:** ![Michael\_TSRichter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@Michael\_TSRichter](https://www.ruby-forum.com/u/Michael_TSRichter)\
**Post date:** [May 21, 2008, 4:35am UTC](https://www.ruby-forum.com/t/13-lines-of-confusion/138212/3 "2008-05-21T04:35:18Z")

</div>

On Tue, May 20, 2008 at 10:02 PM, Michael T. Richter  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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.

the include Rlang::Utility causes the External module to define the e8  
method for classes which include the External module either directly  
or indirectly (e.g. through an included module which includes  
External) but the line

TAG\_CACHED\_ATOM = e8(67)

is evaluated in the context of the module itself, self is External,  
and the External object doesn’t have this method.

Now if you change

include Rlang::Utility  
to  
extend Rlang::Utility

the file will run without error.

If you want classes which include External to have e8 as an instance  
method as well you can both include and extend Rlang::Utility

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![Michael\_TSRichter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@Michael\_TSRichter](https://www.ruby-forum.com/u/Michael_TSRichter)\
**Post date:** [May 21, 2008, 5:15am UTC](https://www.ruby-forum.com/t/13-lines-of-confusion/138212/4 "2008-05-21T05:15:42Z")

</div>

On Wed, 2008-05-21 at 11:34 +0900, Rick DeNatale wrote:

> If you want classes which include External to have e8 as an instance  
> method as well you can both include and extend Rlang::Utility

While I’m not sure I understand the explanation (time to hit the books  
again), the solution you propose works. Time for me to brush up on  
Ruby’s concept of modules again (which is, as is often the case,  
entirely different from everybody else’s take on the topic!:D)
