Reputation: 163
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
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