public
Last active

A demonstration of module inclusion.

  • Download Gist
something.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
class Something
def my_method
puts "(A)"
end
 
module PreExtension
def my_method
puts "(B)"
super
end
end
 
module PostExtension
def my_method
super
puts "(C)"
end
end
 
include PreExtension
include PostExtension
end
 
s = Something.new
s.my_method
# Output:
# >> (A) original functionality
 
# That is, Something#my_method was called, and that was it.
# This is because it comes first in the ancestor chain, and
# it doesn't call super. The methods in the modules are ignored.
 
Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
 
# In general, a module can never override a method in the class
# it's included in. This is because module inclusion works just
# like subclassing. A superclass can't override its subclasses'
# methods either, nor would you expect it to.
 
# On the other hand, modules included later take precedence over
# modules included earlier, and can call super to get the earlier
# modules' implementations. This is because included modules are
# inserted in the ancestor chain directly behind the class. This
# is how the routing code edgerunner mentioned works.
 
class SomethingNew
module Base
def my_method
puts "(A)"
end
end
 
module Extension
def my_method
puts "(B)"
super
end
end
 
include Base
include Extension
end
 
SomethingNew.new.my_method
# Output:
# >> (B)
# >> (A)
 
SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.