如何在 Rails 中随时记录任何方法的猴子补丁
How to log any time any method has been monkey patched in Rails
我想在 Rails 应用程序中任何时候重新定义方法时打印 class 和方法,即使它发生在包含的 gem 中。我知道有一个名为 method_added
的钩子会在重新定义方法时被回调,但我不知道如何使用它来捕获任何被重新定义的东西。
如何使用method_added
?
我将此添加到 boot.rb:
class Module
def method_added(name)
puts "adding #{self.name.underscore.capitalize} #{name}\n"
end
end
但这似乎涵盖了每个方法中的每个方法 class?
您可以使用Module#method_added
钩子来记录所有正在定义的方法,并检查您之前是否已经看到过相同的方法:
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!
但是,这仅适用于加载挂钩方法后添加的方法。明显的替代方法是检查已经定义的方法而不是自己记录它们:
def method_added(meth)
puts "Monkey patching #{meth} in #{self}!" if (instance_methods(false) | private_instance_methods(false)).include?(meth)
super
end
但这不起作用:没有准确指定何时 method_added
挂钩被执行;它可能会在 方法定义之后执行,这意味着检查将始终为真。 (至少我的测试是这样的。)
我想在 Rails 应用程序中任何时候重新定义方法时打印 class 和方法,即使它发生在包含的 gem 中。我知道有一个名为 method_added
的钩子会在重新定义方法时被回调,但我不知道如何使用它来捕获任何被重新定义的东西。
如何使用method_added
?
我将此添加到 boot.rb:
class Module
def method_added(name)
puts "adding #{self.name.underscore.capitalize} #{name}\n"
end
end
但这似乎涵盖了每个方法中的每个方法 class?
您可以使用Module#method_added
钩子来记录所有正在定义的方法,并检查您之前是否已经看到过相同的方法:
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!
但是,这仅适用于加载挂钩方法后添加的方法。明显的替代方法是检查已经定义的方法而不是自己记录它们:
def method_added(meth)
puts "Monkey patching #{meth} in #{self}!" if (instance_methods(false) | private_instance_methods(false)).include?(meth)
super
end
但这不起作用:没有准确指定何时 method_added
挂钩被执行;它可能会在 方法定义之后执行,这意味着检查将始终为真。 (至少我的测试是这样的。)