More verbosely, I have a module Narf
, which provides essential features to a range of classes. Specifically, I want to affect all classes that inherit Enumerable
. So I include Narf
in Enumerable
.
Array
is a class that includes Enumerable
by default. Yet, it is not affected by the late inclusion of Narf
in the module.
Interestingly, classes defined after the inclusion get Narf
from Enumerable
.
Example:
# This module provides essential features
module Narf
def narf?
puts "(from #{self.class}) ZORT!"
end
end
# I want all Enumerables to be able to Narf
module Enumerable
include Narf
end
# Fjord is an Enumerable defined *after* including Narf in Enumerable
class Fjord
include Enumerable
end
p Enumerable.ancestors # Notice that Narf *is* there
p Fjord.ancestors # Notice that Narf *is* here too
p Array.ancestors # But, grr, not here
# => [Enumerable, Narf]
# => [Fjord, Enumerable, Narf, Object, Kernel]
# => [Array, Enumerable, Object, Kernel]
Fjord.new.narf? # And this will print fine
Array.new.narf? # And this one will raise
# => (from Fjord) ZORT!
# => NoMethodError: undefined method `narf?' for []:Array