Ruby:捕获发送到对象的所有方法

Max*_*Max 10 ruby metaprogramming

我正在创建一个奇怪的类,我希望捕获发送到类对象的每个方法.我可以通过method_missing实现我想要的大部分内容,例如

class MyClass
    def method_missing m, *args
        # do stuff
    end
end
Run Code Online (Sandbox Code Playgroud)

那么问题就是MyClass从Object继承的所有实例方法.我可以逐个完成每个方法并重新定义它们,但我希望有一个更灵活的方法.当我尝试触摸那些实例方法时,我尝试过的所有元编程方法都抱怨了NameError.

num*_*407 12

正如@DanCheail的评论和答案所述,如果你使用ruby 1.9+,你应该使用一种BasicObject而不是取消定义的方法Object.在这篇文章发布时,1.8.x的使用仍然非常普遍,尽管1.9已经发布了一段时间.


您可以将对象包装在空白(大部分)代理对象中,而不是尝试"重新定义"任何内容,例如:

class MyProxy
  instance_methods.each do |meth|
    # skipping undef of methods that "may cause serious problems"
    undef_method(meth) if meth !~ /^(__|object_id)/
  end

  def initialize(object)
    @object = object
  end     

  def method_missing(*args)
    # do stuff
    p args
    # ...
    @object.send(*args)
  end
end

MyProxy.new(MyClass.new).whatever
Run Code Online (Sandbox Code Playgroud)


Dan*_*ail 5

如果你正在使用Ruby 1.9,你可以让你的类继承BasicObject来获得一个干净的平板来工作:

http://ruby-doc.org/core-1.9/classes/BasicObject.html

  • 你在`method_missing`里面做什么?如果你做了类似`puts*args`的事情,你将获得一个无限的`method_missing`循环.如果你需要`Kernel`方法,你必须调用`:: Kernel.puts`等. (2认同)