ruby – 获取通过`attr_accessor`定义的所有变量,而不覆盖`attr_accessor`

我正在我的程序上设置一些跟踪代码,并想知道通过attr_accessor定义了哪些方法.使用TracePoint,我可以检测到何时调用attr_accessor,但我不知道如何让它告诉我它收到的参数.有任何想法吗?

解决方法

在问题标题中,您要求提供变量列表,但这会回答问题正文,该正文要求提供已定义方法的列表.

方法不会检查实例变量,如果您开始手动更新或创建其他实例变量,则会引入噪声.

module MethodTracer
  TracePoint.trace(:c_call) do |t|
    if (t.method_id == :attr_accessor)
      t.self.extend(MethodTracer)

      methods = t.self::Methods ||= []
      MethodTracer.send(:define_method,:method_added) {|m| methods << m }
    end
  end

  TracePoint.trace(:c_return) do |t|
    if (t.method_id == :attr_accessor)
      MethodTracer.send(:remove_method,:method_added)
    end
  end
end

class Foo
  attr_accessor :a,:b
  attr_accessor :c

  def foo; end
end

Foo::Methods # => [:a,:a=,:b,:b=,:c,:c=]

我已将方法名称存储在Methods常量中,但显然您可以将它们存储在最方便的地方.

在MethodTracer上定义/删除method_added可确保您不会破坏自己定义的任何Foo.method_added.但是,这种方法确实要求如果在调用attr_accessor之前定义Foo.method_added,则需要在其中调用super.否则,您将跳过MethodTracer定义的临时method_added.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...