Given an existing object "obj", wraps all of its methods. In this case, the wrapper prints a log of the method invocation, and the call stack of the call, but you can modify it to do anything...
virtual_class = class <<obj; self; end
virtual_class.class_eval {
obj.methods.each { |method|
the_alias = method.gsub(/([^?]+)(\??)/, "\\1_orig\\2").to_sym
alias_method the_alias, method
define_method(method) { |*args|
args_str = args.map { |a| a.inspect }.join(", ")
unless method == "to_s"
puts "#{self.inspect_orig}.#{method}(#{args_str}) called from #{caller.inspect}"
end
self.send_orig(the_alias, *args)
}
}
}