0

I'm having a hard time understanding why the following doesn't work:

module M1
  def m1
    p 'm1'
  end

  module ClassMethods
    def m1c
      p 'm1c'
    end
  end

  def self.included base
    base.extend ClassMethods
  end
end

module M2
  include M1

  def m2
    p 'm2'
  end
end


class Foo
  include M2

  def hi
    p 'hi'
  end
end

Foo.new.hi => 'hi'
Foo.new.m1 => 'm1'
Foo.new.m2 => 'm2'
Foo.m1c => undefined method `m1c' for Foo:Class (NoMethodError)

All methods work as expected if I include M1 directly in Foo but it seems DRYer to include it in M2. Am I misunderstanding modules?

1 Answer 1

1

When you do include M1 in M2, the instance methods of M1 as well as the class methods coming from ClassMethods are incorporated into M2 because of the self.included definition in M1.

But when you do include M2 in Foo, you only include the instance methods of M2. The class methods of M2 are not incorporated into Foo.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I was thinking the included hook would be called at each inclusion but it makes sense why it's only called when I include it in M2.
So just move def self.included base; base.extend; ClassMethods; end to M2 and Bob's your uncle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.