Created
January 7, 2009 09:13
-
-
Save bruce/44230 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Widget metaclass ancestors... | |
[Wrapper, Class, Module, Object, Kernel] | |
The 2 `new' methods get invoked... | |
Invoked Widget::new | |
Invoked Wrapper's new | |
The 2 `render_on' methods get invoked... | |
Invoked Wrapping's render_on | |
Invoked Widget#render_on |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# An example to illiustrate that the super-and-extend method wrapping | |
# technique respects `new' methods defined on the wrapped class, provided | |
# that `super' is called. | |
# | |
# For information on the super-and-extend technique, see: | |
# http://codefluency.com/articles/2009/01/03/wrapping-a-method-in-ruby/ | |
# This is the class to wrap | |
class Widget | |
# Example of a scenario where the target class' `new' method is defined, | |
# and `super' is being used, to show invocation order. | |
# | |
# We don't really care about the *order* that the Wrapper's new (just | |
# a hook to extend the instance) fires, the wrapper works as expected. | |
# | |
# Keep in mind overriding `new' is a fairly rare case. | |
# | |
def self.new | |
puts "Invoked Widget::new" | |
super | |
end | |
# The method we're targeting | |
def render_on(document, options = {}) | |
puts "Invoked Widget#render_on" | |
end | |
end | |
# Yeah, the name says it | |
module Wrapper | |
# `super' here invokes Class#new | |
def new | |
puts "Invoked Wrapper's new" | |
super.extend(Wrapping) | |
end | |
module Wrapping | |
def render_on(document, options = {}) | |
puts "Invoked Wrapping's render_on" | |
super # Widget#render_on | |
end | |
end | |
end | |
Widget.extend(Wrapper) | |
puts "Widget metaclass ancestors..." | |
p (class << Widget; self; end).ancestors | |
puts "The 2 `new' methods get invoked..." | |
widget = Widget.new | |
puts "The 2 `render_on' methods get invoked..." | |
widget.render_on(nil) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment