Give one object a method
Define `Loud#shout`, then call `str.extend(Loud)` on `str = "Hello"`. Now `str.shout` returns `"HELLO!!!"`. The method comes from the module, but the change belongs to this string object. section 4.2.3
`extend` adds a module to an object's method-lookup path by including it in the object's singleton class. It is a compact way to give an individual object module-defined behavior without changing its class or other instances. section 13.1.5 section 13.1.6
class Thermometer
class << self
include Convertible
end
end
Opening a class object's singleton class and including `Convertible` shows the lookup change that `extend Convertible` makes to that class object. section 13.1.5
The receiving object determines where the methods appear:
- Inside `class Thermometer`, `extend Convertible` gives the class object callable methods such as `Thermometer.c2f(100)`. It does not add `Convertible` to `Thermometer.ancestors` or give those methods to thermometer instances. By contrast, `include` makes module methods available to instances. section 4.2.3
- On a `Person` instance, `person.extend(Secretive)` changes that person's method lookup. Other `Person` instances need not acquire the module's behavior. section 13.1.6
This selectivity can limit a core-behavior change: extend one string with a module whose `gsub!` calls `super || self`, rather than reopening `String` globally. If a module defines `Module#extended`, an `extend` operation triggers that callback; explicitly including the module in a singleton class instead triggers `included`, even though the resulting lookup path is the same. section 13.2.4 section 15.1.3
