Skip to content

Instantly share code, notes, and snippets.

@Peeja
Created November 5, 2010 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Peeja/664352 to your computer and use it in GitHub Desktop.
Save Peeja/664352 to your computer and use it in GitHub Desktop.
A demonstration of module inclusion.
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]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment