You can use the Module#method_added
hook to keep a record of all methods that are being defined, and check whether you have already seen the same method before:
require 'set'
module LoggingMethodAdded
def method_added(meth)
@methods ||= Set.new
puts "Monkey patching #{meth} in #{self}!" if @methods.include?(meth)
@methods << meth
super
end
end
class Module
prepend LoggingMethodAdded
end
class Foo; def foo; end end
class Foo; def foo; end end
# Monkey patching foo in Foo!
module Bar; def foo; end end
module Bar; def foo; end end
# Monkey patching foo in Bar!
This, however, will only work for methods that are added after you have loaded your hook method. The obvious alternative would be to check the already defined methods instead of recording them yourself:
def method_added(meth)
puts "Monkey patching #{meth} in #{self}!" if (instance_methods(false) | private_instance_methods(false)).include?(meth)
super
end
But this doesn't work: it is not exactly specified when the method_added
hook gets executed; it might get executed after the method has been defined, which means the check will always be true. (At least that's what happened in my tests.)