YoloSnake
YoloSnake

Reputation: 163

Ruby Module has access to class methods it was required in?

I don't quite understand how this works:

module Perimeter
  def perimeter
    sides.inject(0) { |sum, side| sum + side }
  end
end

class Rectangle
  include Perimeter

  def initialize(length, breadth)
    @length = length
    @breadth = breadth
  end

  def sides
    [@length, @breadth, @length, @breadth]
  end
end

class Square
  include Perimeter

  def initialize(side)
    @side = side
  end

  def sides
    [@side, @side, @side, @side]
  end
end

When you call Rectangle.new(2, 3).perimeter it returns 10 as expected.

In this case, the module gets the arguments by calling the sides method from the class. How can a module have access to that method? Is it because of include keyword?

Upvotes: 3

Views: 324

Answers (1)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230296

How can a module have access to that method?

That's exactly what modules do. Basically, you can define a bunch of methods in a module, then include it, and the end result is as if those methods were in your class directly.

If you want more technical, including a module injects it into your class' ancestors chain.

Rectangle.ancestors # => [Rectangle, Perimeter, Object, Kernel, BasicObject]

You might be familiar with Enumerable module. It contains many useful methods, like reduce, map, count and others. They're all implemented with method each and that's the one method that Enumerable module does not implement. It's the missing piece. Now, if you have a class (some kind of collection, perhaps. Genealogy tree or something) and it implements each, you can include Enumerable in that class and voilà, now you can map your collection. Same thing in your case with perimeter and sides.

Upvotes: 4

Related Questions