Skip to content

Instantly share code, notes, and snippets.

@robolson
Created February 14, 2010 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save robolson/303904 to your computer and use it in GitHub Desktop.
Save robolson/303904 to your computer and use it in GitHub Desktop.
# Blog post at
# http://pivotallabs.com/users/rolson/blog/articles/1162-redefine-a-method-from-a-module-like-a-gentleman
module Teacher
def self.included(base)
base.extend ClassMethods
base.overwrite_initialize
base.instance_eval do
def method_added(name)
return if name != :initialize
overwrite_initialize
end
end
end
module ClassMethods
def overwrite_initialize
class_eval do
unless method_defined?(:custom_initialize)
define_method(:custom_initialize) do
puts "teacher initialized"
original_initialize
end
end
if instance_method(:initialize) != instance_method(:custom_initialize)
alias_method :original_initialize, :initialize
alias_method :initialize, :custom_initialize
end
end
end
end
end
class Person
include Teacher
def initialize
puts "person initialized"
end
end
if __FILE__ == $PROGRAM_NAME
require 'test/unit'
class TestTeacher < Test::Unit::TestCase
def test_output_of_initialize
out = capture_stdout { Person.new }
lines = out.string.split(/\n/)
assert_equal "teacher initialized", lines[0]
assert_equal "person initialized", lines[1]
end
end
# Test helper for capturing input to standard out
# http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/
require 'stringio'
module Kernel
def capture_stdout
out = StringIO.new
$stdout = out
yield
return out
ensure
$stdout = STDOUT
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment