获取通过`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
常量中,但显然您可以将它们存储在最方便的地方。
在method_added
上定义/删除method_added
可确保您不会破坏自己定义的任何Foo.method_added
。 但是,这种方法确实要求如果在调用Foo.method_added
之前定义attr_accessor
,则需要在其中调用super
。 否则,您将跳过method_added
定义的临时MethodTracer
。
你可以使用obj.methods()
来查找实例上的所有可用方法(包括来自超类的方法),并使用obj.methods(false)
来获取当前单例对象上定义的方法。 我不确定是否可以检测这些方法是否通过attr_accessor
创建