Search code examples
rubyincludeextend

Can you extend self.included?


Here's what I want to do, roughly:

module Foo

  def self.included base
    base.extend ClassMethods
  end

end

module Bar
  extend Foo

  module ClassMethods
    def hi
      return "hello!"
    end
  end
end

class Baz
  include Bar
end

Baz.hi #=> "hello!'

but instead I get

NoMethodError: undefined method `hi' for Baz:Class

If it's not clear, more generally what I'm trying to do is create one module that contains logic for the included callback, which several other modules then extend, and I want them to use the included callback from the extended module (but if, e.g., Bar extends Foo, I'd like self to refer to Bar in the the closure for included, if possible).

Probably that's a bit confusing.


Solution

  • Problem was that I needed to define included rather than self.included for Bar to get included as a class method. The following does what I wanted:

    module Foo
    
      def included base
        base.extend self::ClassMethods
      end
    
    end
    
    module Bar
      extend Foo
    
      module ClassMethods
        def hi
          return "hello!"
        end
      end
    end
    
    class Baz
      include Bar
    end
    
    Baz.hi #=> "hello!'