Recap: include and the ancestor chain
One line you've already written, looked at closely
In Ruby modules: include/extend you wrote include SomeModule inside a class body to mix a module's methods into every instance of the class. This course doesn't reteach that. It answers a sharper question the earlier course only touched on: when Ruby looks for a method, in what order does it check the places the method could live?
module Startable
def start
"engine turns over"
end
end
class Car
include Startable
def start
"car starts smoothly"
end
end
Car includes Startable and also defines its own start. A call to Car.new.start runs only one of these two method bodies. Which one runs, and why, comes down to one method every class responds to: .ancestors.
.ancestors: the search order
Car.ancestors
# [Car, Startable, Object, Kernel, BasicObject]
That array is the order Ruby walks when you call a method on a Car instance. Ruby checks Car, then Startable, then Object, then Kernel, then BasicObject. It stops at the first place that defines the method being called.
Car.new.start
# "car starts smoothly"
Car comes first in the array and defines start, so the search stops there. Startable#start exists and sits in the ancestor chain, but it never runs. Car's own method wins because Ruby checks Car first.
When the class doesn't define it
class Motorcycle
include Startable
end
Motorcycle.new.start
# "engine turns over"
Motorcycle never defines start. The search starts at Motorcycle, moves through its ancestors, reaches Startable and stops there. It's the same algorithm with a different outcome, because this time nothing earlier in the chain got in the way.
The pattern so far
include inserts a module right after the class in .ancestors, and that's the whole rule. The class's own method sits before the module in the chain, so it wins when both define the same name. The module only gets a turn when the class doesn't define that method.
That fact, module after the class, is about to get a counterpart. The rest of this course is about one more keyword that puts a module in a different spot in the same array, and what follows from where it lands.
Where this course goes
There are seven lessons. This one recaps where include puts a module. Then come prepend and where it lands, .ancestors for both side by side, and a trace showing which method body runs first. After that: how super behaves inside a prepended module, both keywords on one class, and a final lesson on choosing between them. Each claim is checked by running code.
Key takeaways
.ancestorsreturns the ordered list Ruby walks to find a method.includeinserts a module right after the class in that list:[Car, Startable, Object, Kernel, BasicObject].- Because the class comes first, its own method wins over an included module's method with the same name.
- When the class doesn't define the method, the search continues down the chain and reaches the module.
Keep going with lesson 2
prepend inserts a module before the class
Shows that prepend puts the module before the class, so its method runs first and controls the call.
A free account also gives you the quizzes, your progress and notes, and the discussion.