10

Why is this module's initialize method not called when it is included in Temp class?

module Temp
  def initialize
    p "asdasd"
  end
end

class Swap
  include Temp
  def initialize
    p "m in class"
  end
end

s = Swap.new

m in class

3 Answers 3

18

The Swap class overrides the initialize method defined in the Temp module. When Ruby attempts to find a method it searches the inheritance hierarchy starting at the most derived class/module. In this case the search ends at the Swap class.

Overridden methods don't get called unless you explicitly call them with super. For example

class Swap
  include Temp
  def initialize
    p "m in  class"
    super
  end
end

will call Temp#initialize from Swap#initialize.

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

Comments

9

Because you defined initialize in both the class and module, and Ruby will look for methods in its own class before moving up to other classes/module.

To see the chain of ancestors, try this

s = Swap.new
puts s.class.ancestors

You will see the chain, and know where Ruby starts to find its function.

Comments

-3

It only calls the constructor within scope.

If you want to invoke the modules initializer method you have to call it directly like so.

module Temp
  def self.initialize
    p "asdasd"
  end
end

class Swap
  include Temp
  def initialize
    p "m in class"
    Temp.initialize
  end
end

s = Swap.new

2 Comments

In this example, since scope isn't really needed, this works. But if the Temp#initialize method needs to be called in the scope of the Swap instance, you'll run into problems.
Calling Temp.initialize is an anti-pattern--super is the right way to call the initialize method of the super-class.

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.