I am setting some trace code on my program, and would like to know which methods are defined through attr_accessor
. Using TracePoint
, I can detect
In the question title, you asked for a list of variables, but this answers the question body, which asked for a list of the methods defined.
This method doesn't bother checking instance variables, which will have noise introduced if you begin manually updating or creating other instance variables.
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=]
I've stored the method names in the Methods
constant, but obviously you can store them wherever is most convenient for you.
Defining/removing method_added
on MethodTracer
ensures that you don't clobber any Foo.method_added
you've defined yourself. This methodology, however, does require that if you define Foo.method_added
before your calls to attr_accessor
, you will need to call super
inside it. Otherwise you will skip the temporary method_added
defined by MethodTracer
.
you can use obj.methods()
to find all the methods available on the instance (inc methods from superclasses), and obj.methods(false)
to get only the method defined on current singleton object. I'm not sure its possible to detect if these methods where created via attr_accessor
though