Skip to content

Instantly share code, notes, and snippets.

@bruce
Created January 7, 2009 09:13
Show Gist options
  • Save bruce/44230 to your computer and use it in GitHub Desktop.
Save bruce/44230 to your computer and use it in GitHub Desktop.
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
# 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