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

前端 未结 2 1201
无人共我
无人共我 2021-01-04 23:11

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

2条回答
  •  情话喂你
    2021-01-04 23:13

    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.

提交回复
热议问题