rubyirblearn-ruby-the-hard-way

Ruby Include Module in IRB


I'm working through Zed Shaw's Learn Ruby The Hard Way and I'm having an issue including a module in IRB. In exercise 25, we define a new module Ex25, require it in IRB, and then can use its various methods through the namespace of that module, e.g. Ex25.break_words(sentence). In the Extra Credit, it's stated that typing include Ex25 will basically add the methods from the module into the current "space" (not sure what to call it) and you can then call them without explicitly referring to the module, e.g. break_words(sentence). When I do this, however, I'm getting an "undefined method" error. Any help / explanation would be greatly appreciated, thanks!


Solution

  • That's an error in the book. The methods in Ex25 are class methods. include adds instance methods to the "current space." Remove self from the method definitions and it'll work:

    module Ex25
      def break_words(stuff)
        stuff.split(' ')
      end
    end
    
    include Ex25
    break_words 'hi there'  # => ["hi", "there"]
    

    If you're curious, here's some more detail about what's going on: The place where the methods are included—the "current space"—is the Object class:

    Object.included_modules  # => [Ex25, Kernel]
    

    All Object instances gain the included methods ...

    Object.new.break_words 'how are you?'  # => ["how", "are", "you?"]
    

    ... and the top-level is just an Object instance:

    self.class  # => Object
    

    But wait. If the top-level is an Object instance, why does it respond to include? Isn't include an instance method of Module (and its subclass, Class)? The answer is that the top-level has a singleton method ...

    singleton_methods.include? "include"  # => true
    

    ... which we can assume forwards to the Object class.