Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
require 'test/unit/assertions'
include Test::Unit::Assertions
assert_equal "1.9.2", RUBY_VERSION
# A Ruby meta-programming puzzle for polite programmers.
# This puzzle was created by Matt Wynne (@mattwynne) on 2011-04-10 inspired by Jim Weirich's
# talk at the Scottish Ruby Conference 2011.
# The challenge is: you have a class Foo which you want to monkey-patch, but politely.
# Here's the default behaviour of Foo
class Foo
def bar
assert_equal "bar",
module Baz
def bar
"wee" + super
# # Unfortunately, if we try to monkey-patch Foo like this, it won't work
# class Foo
# include Baz
# end
# # this fails:
# assert_equal "weebar",
# This is because the include trick inserts the module Baz higher into the inheritance tree
# meaning Foo's own implementation of bar is hit first.
# So let's write a helper method that can do the patching for us, by extending each instance
# of Foo as it is created.
def extend_every(type_to_patch, module_to_apply)
patcher = do
def new(*args)
type_to_patch.class_eval do
extend patcher
extend_every(Foo, Baz)
assert_equal "weebar",
# Great, but we've had to hard-code Baz onto line 38. How can we make this method generic?

This comment has been minimized.

Copy link

commented Apr 10, 2011

My attempt at solving this is in my fork above; basically, using define_method gives us the closure-style behaviour we need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.