2011-08-25 43 views
10

我正在制作一个奇怪的类,我想捕获发送到类的对象的每个方法。我可以通过method_missing实现我想要的大部分内容,例如Ruby:捕获发送到对象的所有方法

class MyClass 
    def method_missing m, *args 
     # do stuff 
    end 
end 

问题在于MyClass从Object继承的所有实例方法。我可以一一浏览每种方法并重新定义它们,但我希望采取更灵活的方法。当我尝试触摸这些实例方法时,我尝试过的所有元编程方法都有一个NameError抱怨。

回答

11

诚如@DanCheail的评论和答复指出,如果您使用的是Ruby 1.9或更高版本,则应使用BasicObject而不是未定义的方法Object。在本贴发布时,尽管1.9版已经发布了一段时间,1.8.x的使用仍然非常普遍。


,而不是试图“重新定义”什么,你可以换你的对象在冲裁(大部分)代理对象,像:

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 
+0

这就是我正在寻找的! – Max

+0

使用BasicObject会好得多,因为它完成同样的事情并且更安全。 – Max

+0

已记录。当发布这个答案时,1.8在生产场景中仍然很常见,因此'BasicObject'还不存在。 – numbers1311407

5

如果您使用Ruby 1.9的,你可以有你的类继承BasicObject得到一个干净的石板从工作:

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

+0

这就是我正在寻找的东西,但是当定义'method_missing'时,一个微不足道的尝试给了我一个'SystemStackError:堆栈层次太深'。嗯...... – Max

+2

你在做什么'method_missing'?如果你做了'puts * args'之类的东西,你将得到一个无限的'method_missing'循环。如果你需要一个'Kernel'方法,你必须调用':: Kernel.puts'等。 – numbers1311407

1

如果你使用Ruby 1.8你可以考虑使用blankslate宝石。

相关问题