0

我想知道是否有可能做到这样,如果我有类似的东西

class Test

  attr_reader :access_times
  def initialize
    @access_times = 0
  end

  def get_two
    2
  end

  ...
end

t = Test.new

任何访问t都会在实际运行该方法之前运行一段特定的代码?

例如,如果我突然决定说,我使用语法t.get_two的事实会加1。或者我做了一个检查,它也会加1。访问继承的任何方法或属性也会使变量加 1 ..@access_timest.is_a?(Test)@access_timesTest

如果可能的话,基本上我想在.语法中添加一些东西。

我不是在问这是好还是坏的代码,只是它是否可能以及如何完成。我通常不会使用它,因为我可以手动将增量逻辑添加到每个方法,并用方法替换所有直接实例变量访问(甚至像is_a?和其他继承自的东西Object

4

3 回答 3

0

如果您不需要所有东西都是独立的,那么建议只是扩展ActiveModel::Callbacks. 只需扩展类,您将拥有 before_filter 的所有功能,而不需要所有其他 Rails 东西。

于 2012-08-07T19:30:32.873 回答
0

一个非常核心的版本将是使用set_trace_funchttp ://apidock.com/ruby/Kernel/set_trace_func

这允许您订阅整个程序中触发的所有 ruby​​ 事件,这可能是大量的调用......

我认为没有用于注册任意方法调用的内置挂钩。您可以通过缺少方法、方法链接或委托来实现某些东西,但这取决于您的要求。

于 2012-08-07T19:37:35.763 回答
0

这是根据您的描述的解决方法。基本上它将为每个实例方法增加@access_times,并且该方法也执行它之前所做的事情。

class Test
  attr_accessor :access_times

  def initialize
    @access_times = 0
  end

  def get_two
    2
  end
end

class Test
  @@im = instance_methods

  @@im.each do |m|
    class_eval <<-END
      alias temporary #{m}
    END

    define_method(m) do |*args, &block|
      @access_times += 1
      temporary(*args, &block)
    end
  end

  undef :temporary
end

Test.new.get_two # => @access_times += 1 and original get_two is called: 2

虽然这段代码没有按预期工作,但我稍后会看一下。谢谢。

于 2012-08-08T06:49:09.297 回答