2016-05-22 4 views
2

Tracepointを使用してプログラムで行われたすべてのメソッド呼び出しを追跡したいと思います。 Tracepointは特定のクラスへの呼び出しを追跡しません。たとえば:なぜ `String#size`のようなメソッドへのトレース・トレースはトレースされませんか?

class A; def call_to_method_a; puts 'test3' end; end 

TracePoint.trace(:call, :c_call) do |tp| 
    p [tp.lineno, tp.defined_class, tp.method_id, tp.event] 
end 

'test2'.size 
# No Tracepoint output 

A.new.call_to_method_a 
# [26, A, :call_to_method_a, :call] 

TracepointはラインA.new.call_to_method_aのための呼び出しを記録し、私はそれがまた `文字列#サイズ」への呼び出しを追跡するために期待したいです。それはなぜですか?

答えて

3

これらのメソッドはRubyではなくCで定義されているからです。 :callは、Ruby定義のメソッド呼び出しのみをトレースします。 C定義のメソッドをトレースするには、:c_callを使用する必要があります。

+1

良いコール、 ':c_call'を引数として追加するのを忘れました。私はc_callを追加するために少し例を変更しましたが、 'test2'.sizeを呼び出すことはまだTracepointによる呼び出しを表示しません。思考? – Lush

+2

生成されたコードを見たいと思うかもしれません。文字列の内容とメソッド呼び出しのターゲットの両方がコンパイル時にわかっており( 'String#size'に副作用がないため)、コンパイラは呼び出しを完全に最適化することができます。結局のところ、デッドコードであり、何の効果もありません。あなたは使用している実装を指定していませんが、少なくともJRubyはデッドコードの削除を実行することがわかります。 –

関連する問題