在类中的每个方法之前运行代码(Ruby)

时间:2011-08-09 04:07:55

标签: ruby class methods

我想跟踪在我构建的类的实例上运行的所有方法。

目前我这样做:

class MyClass
    def initialize
        @completed = []
    end

    # Sends a welcome and information pack to the person who requested it
    def one_of_many_methods
    unless @completed.include? __method__
            # Do methody things
            @completed.push __method__
        end
    end
    alias :another_name :one_of_many_methods
    # Calling myClassInstance.another_name will insert
    # :one_of_many_methods into @completed.
    # Methody things should not now be done if .another_name
    # or .one_of_many_methods is called.
end

但是,当我班上有很多方法时,这会非常费力。我在重复自己!有没有办法跟踪被调用的方法,只允许它们被调用一次,就像我上面所做的那样,但是不必在每个方法中重复那个块?

谢谢!

(PS。我正在使用Ruby 1.9)

4 个答案:

答案 0 :(得分:7)

这听起来像是Proxy对象的完美用例。幸运的是,Ruby的动态特性使得实现起来非常简单:

class ExecuteOnceProxy

  def initialize(obj)
    @obj = obj
    @completed = []
  end

  def method_missing(method, *args)
    unless @completed.include?(method)
      args.empty? ? @obj.send(method) : @obj.send(method, args)
      @completed << method
    end
  end
end

只需在构造函数中传递原始对象即可初始化代理:

proxy = ExecuteOnceProxy.new(my_obj)

答案 1 :(得分:2)

method_missing


有些框架可以做这样的事情,但回答你的问题,是的,有一个简单的方法。

只编写一次代码的简单方法是前端整个类并实现method_missing.然后,您可以一次发现一个真实的方法,因为每个方法都被发现“缺失”了初次通话。

答案 2 :(得分:1)

我认为你的问题有新的解决方案。

很久以前,Tobias Pfeiffer发布了after_do gem

答案 3 :(得分:0)

这不是答案,因为我没有足够的声誉发表评论,但请注意@emboss发布的答案中有错误(缺少明星)。

args.empty? ? @obj.send(method) : @obj.send(method, args)

应该是

args.empty? ? @obj.send(method) : @obj.send(method, *args)

否则该方法将收到一个arg:你试图传递它的args数组。