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

发布于 2024-12-01 10:33:09 字数 288 浏览 1 评论 0原文

我正在创建一个奇怪的类,我想捕获发送到该类对象的每个方法。我可以使用 method_missing 实现我想要的大部分功能,例如

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

问题是 MyClass 从 Object 继承的所有实例方法。我可以逐一检查每种方法并重新定义它们,但我希望有一种更灵活的方法。当我尝试接触这些实例方法时,我尝试过的所有元编程方法都会抱怨 NameError。

I'm making a weird class where I want to catch every method sent to an object of the class. I can achieve most of what I want with method_missing e.g.

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

The problem then is all of the instance methods that MyClass inherits from Object. I could go through each method one-by-one and redefine them, but I was hoping for a more flexible approach. All of the metaprogramming methods I've tried have complained with a NameError when I try to touch those instance methods.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦幻的味道 2024-12-08 10:33:09

正如@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

As noted in the comments and the answer from @DanCheail, if you're using ruby 1.9+ you should use a BasicObject rather than undefining methods of Object. At the time of this posting usage of 1.8.x was still quite prevalent, even though 1.9 had been released for some time.


Rather than attempting to "redefine" anything, you could wrap your object in a blanked (for the most part) proxy object, something like:

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
蓝颜夕 2024-12-08 10:33:09

如果您使用的是 Ruby 1.9,则可以让您的类继承 BasicObject 以获得全新的工作状态:

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

If you're using Ruby 1.9, you can have your class inherit from BasicObject to get a clean slate to work from:

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

书间行客 2024-12-08 10:33:09

如果您使用 Ruby 1.8,您可以考虑使用 Blankslate gem。

If you're using Ruby 1.8 you can consider using the blankslate gem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文