n_x_l
n_x_l

Reputation: 1610

Get all variables defined through `attr_accessor` without overriding `attr_accessor`

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 when attr_accessor is called, but I don't know how to get it to tell me the arguments it received. Any ideas?

Upvotes: 9

Views: 1958

Answers (2)

user513951
user513951

Reputation: 13690

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.

Upvotes: 8

maniacalrobot
maniacalrobot

Reputation: 2463

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

Upvotes: 0

Related Questions