如何在任何时候记录任何方法已经在Rails猴子修补

mar*_*hon -1 ruby monkeypatching ruby-on-rails

我想在Rails应用程序中重新定义方法时打印类和方法,即使它发生在包含的gem中.我知道有一个叫做的钩子method_added在重新定义一个方法时会被回调,但是我不知道怎么用它来捕获重新定义的东西.

我该怎么用method_added

我把它添加到boot.rb:

class Module
  def method_added(name)
    puts "adding #{self.name.underscore.capitalize}  #{name}\n"
  end
end
Run Code Online (Sandbox Code Playgroud)

但这似乎是每个班级中的每一种方法都在捕捉?

Jör*_*tag 6

您可以使用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!
Run Code Online (Sandbox Code Playgroud)

但是,这仅适用于加载hook方法后添加的方法.显而易见的替代方法是检查已定义的方法而不是自己记录它们:

def method_added(meth)
  puts "Monkey patching #{meth} in #{self}!" if (instance_methods(false) | private_instance_methods(false)).include?(meth)
  super
end
Run Code Online (Sandbox Code Playgroud)

但是,这并不工作:它是不完全指定method_added挂钩被执行; 它可能在定义方法执行,这意味着检查将始终为true.(至少那是我测试中发生的事情.)