“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay who are based in Denmark...”

Rob Lacey
Senior Software Engineer, UK

extending a class included in a module

This seemed pretty straight forward to me.

module Something
  def api
   @api ||= Api.new
  end
  class Api
    def do_something
      :doing_something
    end
  end
end

class Thing
  include Something
  class Api
    def do_thing
      :doing_thing
    end
  end
end

Seems legitimate, just extend the class that I’ve included in my module.

2.1.2 :021 > Thing.new.api.do_thing
NoMethodError: undefined method `do_thing' for #<Something::Api:0x007f946546afe0>
	from (irb):21
	from /Users/rl/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'

Wrong! Hmmzz…. I guess the class that the module is instantiating from is the one in the module not the one included in my Thing class I need to ensure that I instantiate from the right one.

module Something
  def api
   @api ||= self.class::Api.new
  end
  class Api
    def do_something
      :doing_something
    end
  end
end

class Thing
  include Something
  class Api
    def do_thing
      :doing_thing
    end
  end
end
</pre></code>

Works, but hang on.

<pre><code>
2.1.2 :019 > Thing.new.api.do_thing
 => :doing_thing 
2.1.2 :020 > Thing.new.api.do_something
NoMethodError: undefined method `do_something' for #<Thing::Api:0x007fa60a4c1fc8>
	from (irb):20
	from /Users/rl/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'

The class is not using the class I’ve defined in my module at all.

module Something
  def api
   @api ||= self.class::Api.new
  end
  class Api
    def do_something
      :doing_something
    end
  end
end

class Thing
  include Something
  class Api < Something::Api
    def do_thing
      :doing_thing
    end
  end
end

Better,