2015-12-23 3 views
8

私は自分のプログラムにトレースコードを設定していますが、どのメソッドがattr_accessorで定義されているか知っています。 TracePointを使用すると、attr_accessorが呼び出されたときを検出できますが、受け取った引数をどのように取得するのかわかりません。何か案は?`attr_accessor`によって定義されたすべての変数を` attr_accessor`をオーバーライドしないで取得します

+1

インスタンス変数_all_を取得できます。これで十分でない場合は、attr_accessorをある意味で計測する必要があります。これを避ける方法はありません。 –

+0

メソッドが 'attr_accessor'を使って定義されているか、あるいはインスタンス変数のアクセサメソッドであるメソッドを探しているかどうかは重要ですか? –

+0

attr_accessorは私の後です。残りはTracePointで簡単に手に入ります。 –

答えて

0

obj.methods()を使用すると、インスタンス上で利用可能なすべてのメソッド(スーパークラスからのメソッド)と、現在のシングルトンオブジェクトで定義されたメソッドのみを取得するobj.methods(false)を取得できます。私は、これらのメソッドがどこで作成されたかを検出することができないのかどうかは確かではありません。

+0

これは本当に質問に答えるものではありませんか? :) –

6

質問のタイトルでは、変数のリストを尋ねましたが、これは定義されたメソッドのリスト。

このメソッドでは、インスタンス変数を手動で更新または作成するとノイズが発生することがあります。

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_addedMethodTracerに定義/削除すると、自分で定義したFoo.method_addedが壊れないようになります。しかし、この方法論では、attr_accessorへの呼び出しの前にFoo.method_addedを定義する場合は、superを呼び出す必要があります。それ以外の場合はで定義された一時的なmethod_addedはスキップされます。

+3

これは唯一の正解と思われる。 – sawa

+1

補足として、 'attr_accessor'に渡されたメソッドの名前を取得するために' TracePoint'を使う方法を理解しようとしました。私はそれが非常に不可能であることが分かった。 –

+2

私はしようとしました。そしてOPもそうだった。それが問題の全体のポイントでした。あなただけが解決策に達しました。 – sawa

関連する問題