class TracePoint

[edit]

要約

Kernel.#set_trace_func と同様の機能をオブジェクト指向的な API で提供するクラスです。

例:例外に関する情報を収集する

trace = TracePoint.new(:raise) do |tp|
  p [tp.lineno, tp.event, tp.raised_exception]
end
# => #<TracePoint:0x007f786a452448>

trace.enable
# => false

0 / 0
# => [5, :raise, #<ZeroDivisionError: divided by 0>]

TracePoint.new または、TracePoint.trace で指定したブロックは、メソッドの引数(上記の例では :raise)に対応するイベントが発生した時に呼び出されます。

発生するイベントの詳細については、TracePoint.new を参照してください。

参考

目次

特異メソッド
インスタンスメソッド

特異メソッド

new(*events) {|obj| ... } -> TracePoint[permalink][rdoc][edit]

新しい TracePoint オブジェクトを作成して返します。トレースを有効にするには TracePoint#enable を実行してください。

例:irb で実行した場合

trace = TracePoint.new(:call) do |tp|
    p [tp.lineno, tp.defined_class, tp.method_id, tp.event]
end
# => #<TracePoint:0x007f17372cdb20>

trace.enable
# => false

puts "Hello, TracePoint!"
# ...
# [69, IRB::Notifier::AbstractNotifier, :printf, :call]
# ...

トレースを無効にするには TracePoint#disable を実行してください。


trace.disable
[PARAM] events:
トレースするイベントを StringSymbol で任意の数指定します。
:line

式の評価。

:class

クラス定義、特異クラス定義、モジュール定義への突入。

:end

クラス定義、特異クラス定義、モジュール定義の終了。

:call

Ruby で記述されたメソッドの呼び出し。

:return

Ruby で記述されたメソッド呼び出しからのリターン。

:c_call

C で記述されたメソッドの呼び出し。

:c_return

C で記述されたメソッド呼び出しからのリターン。

:raise

例外の発生。

:b_call

ブロックの開始。

:b_return

ブロックの終了。

:thread_begin

スレッドの開始。

:thread_end

スレッドの終了。

:fiber_switch

ファイバーの切り替え。

:script_compiled

スクリプトのコンパイル

指定イベントに関連しない情報を取得するメソッドを実行した場合には RuntimeError が発生します。



TracePoint.trace(:line) do |tp|
    p tp.raised_exception
end
# => RuntimeError: 'raised_exception' not supported by this event

イベントフックの外側で、発生したイベントに関連する情報を取得するメソッドを実行した場合には RuntimeError が発生します。



TracePoint.trace(:line) do |tp|
  $tp = tp
end
$tp.lineno # => access from outside (RuntimeError)

他のスレッドから参照する事も禁じられています。

[EXCEPTION] ArgumentError:
ブロックを指定しなかった場合に発生します。
stat -> object[permalink][rdoc][edit]

TracePoint の内部情報を返します。

返り値の内容は実装依存です。将来変更される可能性があります。

このメソッドは TracePoint 自身のデバッグ用です。

trace(*events) {|obj| ... } -> TracePoint[permalink][rdoc][edit]

新しい TracePoint オブジェクトを作成して自動的にトレースを開始します。TracePoint.new のコンビニエンスメソッドです。

[PARAM] events:
トレースするイベントを StringSymbol で任意の数指定します。指定できる値については TracePoint.new を参照してください。


trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] }
# => #<TracePoint:0x007f786a452448>

trace.enabled? # => true
[EXCEPTION] ThreadError:
ブロックを指定しなかった場合に発生します。

インスタンスメソッド

binding -> Binding[permalink][rdoc][edit]

発生したイベントによって生成された Binding オブジェクトを返します。



def foo(ret)
  ret
end
trace = TracePoint.new(:call) do |tp|
  p tp.binding.local_variables # => [:ret]
end
trace.enable
foo 1
callee_id -> Symbol | nil[permalink][rdoc][edit]

イベントが発生したメソッドの呼ばれた名前を Symbol で返します。トップレベルであった場合は nil を返します。

[EXCEPTION] RuntimeError:
イベントフックの外側で実行した場合に発生します。

class C
  def method_name
  end
  alias alias_name method_name
end

trace = TracePoint.new(:call) do |tp|
  p [tp.method_id, tp.callee_id] # => [:method_name, :alias_name]
end
trace.enable do
  C.new.alias_name
end

[SEE_ALSO] TracePoint#method_id

defined_class -> Class | module[permalink][rdoc][edit]

メソッドを定義したクラスかモジュールを返します。



class C; def foo; end; end
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class # => C
end.enable do
  C.new.foo
end

メソッドがモジュールで定義されていた場合も(include に関係なく)モジュールを返します。



module M; def foo; end; end
class C; include M; end;
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class # => M
end.enable do
  C.new.foo
end

[注意] 特異メソッドを実行した場合は TracePoint#defined_class は特異クラスを返します。また、Kernel.#set_trace_func の 6 番目のブロックパラメータは特異クラスではなく元のクラスを返します。



class C; def self.foo; end; end
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class # => #<Class:C>
end.enable do
  C.foo
end

Kernel.#set_trace_funcTracePoint の上記の差分に注意してください。

[SEE_ALSO] [ruby-core:50864]

disable -> bool[permalink][rdoc][edit]
disable { ... } -> object

self のトレースを無効にします。

実行前の TracePoint#enabled? を返します。(トレースが既に有効であった場合は true を返します。そうでなければ false を返します)



trace.enabled? # => true
trace.disable  # => false (実行前の状態)
trace.enabled? # => false
trace.disable  # => false

ブロックが与えられた場合、ブロック内でのみトレースが無効になります。この場合はブロックの評価結果を返します。



trace.enabled?   # => true

trace.disable do
  trace.enabled? # => false
end

trace.enabled?   # => true

[注意] イベントフックのためのメソッドに、ブロックの外側で参照した場合は RuntimeError が発生する事に注意してください。

trace.enable { p trace.lineno }
# => RuntimeError: access from outside

[SEE_ALSO] TracePoint#enable, TracePoint#enabled?

enable -> bool[permalink][rdoc][edit]
enable { ... } -> object

self のトレースを有効にします。

実行前の TracePoint#enabled? を返します。(トレースが既に有効であった場合は true を返します。そうでなければ false を返します)



trace.enabled?  # => false
trace.enable    # => false (実行前の状態)

# トレースが有効

trace.enabled?  # => true
trace.enable    # => true (実行前の状態)

# 引き続きトレースが有効

ブロックが与えられた場合、ブロック内でのみトレースが有効になります。この場合はブロックの評価結果を返します。



trace.enabled?   # => false

trace.enable do
  trace.enabled? # => true
end

trace.enabled?   # => false

[注意] イベントフックのためのメソッドにブロックの外側で参照した場合は RuntimeError が発生する事に注意してください。



trace.enable { p trace.lineno }
# => RuntimeError: access from outside

[SEE_ALSO] TracePoint#disable, TracePoint#enabled?

enabled? -> bool[permalink][rdoc][edit]

self のトレースが有効な場合に true を、そうでない場合に false を返します。

[SEE_ALSO] TracePoint#enable, TracePoint#disable

eval_script -> String | nil[permalink][rdoc][edit]

script_compiledイベント発生時にコンパイルされたソースコードを返します。ファイルから読み込んだ場合は、nilを返します。



TracePoint.new(:script_compiled) do |tp|
  p tp.eval_script # => "puts 'hello'"
end.enable do
  eval("puts 'hello'")
end
[EXCEPTION] RuntimeError:
:script_compiled イベントのためのイベントフックの外側で実行した場合に発生します。
event -> Symbol[permalink][rdoc][edit]

発生したイベントの種類を Symbol で返します。

発生するイベントの詳細については、TracePoint.new を参照してください。

[EXCEPTION] RuntimeError:
イベントフックの外側で実行した場合に発生します。


def foo(ret)
  ret
end
trace = TracePoint.new(:call, :return) do |tp|
  p tp.event
end
trace.enable
foo 1
# => :call
# :return
inspect -> String[permalink][rdoc][edit]

self の状態を人間に読みやすい文字列にして返します。



def foo(ret)
  ret
end
trace = TracePoint.new(:call) do |tp|
  p tp.inspect # "#<TracePoint:call `foo'@/path/to/test.rb:1>"
end
trace.enable
foo 1
instruction_sequence -> RubyVM::InstructionSequence[permalink][rdoc][edit]

script_compiledイベント発生時にコンパイルされた RubyVM::InstructionSequenceインスタンスを返します。



TracePoint.new(:script_compiled) do |tp|
  p tp.instruction_sequence # => <RubyVM::InstructionSequence:block in <main>@(eval):1>
end.enable do
  eval("puts 'hello'")
end
[EXCEPTION] RuntimeError:
:script_compiled イベントのためのイベントフックの外側で実行した場合に発生します。
lineno -> Integer[permalink][rdoc][edit]

発生したイベントの行番号を返します。

[EXCEPTION] RuntimeError:
イベントフックの外側で実行した場合に発生します。


def foo(ret)
  ret
end
trace = TracePoint.new(:call, :return) do |tp|
  tp.lineno
end
trace.enable
foo 1
# => 1
# 3
method_id -> Symbol | nil[permalink][rdoc][edit]

イベントが発生したメソッドの定義時の名前を Symbol で返します。トップレベルであった場合は nil を返します。

[EXCEPTION] RuntimeError:
イベントフックの外側で実行した場合に発生します。

class C
  def method_name
  end
  alias alias_name method_name
end

trace = TracePoint.new(:call) do |tp|
  p [tp.method_id, tp.callee_id] # => [:method_name, :alias_name]
end
trace.enable do
  C.new.alias_name
end

[SEE_ALSO] TracePoint#callee_id

parameters -> [object][permalink][rdoc][edit]

現在のフックが属するメソッドまたはブロックのパラメータ定義を返します。フォーマットは Method#parameters と同じです。

[EXCEPTION] RuntimeError:
:call、:return、:b_call、:b_return、:c_call、:c_return イベントのためのイベントフックの外側で実行した場合に発生します。


def foo(a, b = 2)
end
TracePoint.new(:call) do |tp|
  p tp.parameters # => [[:req, :a], [:opt, :b]]
end.enable do
  foo(1)
end

[SEE_ALSO] Method#parameters, UnboundMethod#parameters, Proc#parameters

path -> String[permalink][rdoc][edit]

イベントが発生したファイルのパスを返します。

[EXCEPTION] RuntimeError:
イベントフックの外側で実行した場合に発生します。


def foo(ret)
  ret
end
trace = TracePoint.new(:call) do |tp|
  p tp.path # => "/path/to/test.rb"
end
trace.enable
foo 1
raised_exception -> Exception[permalink][rdoc][edit]

発生した例外を返します。

[EXCEPTION] RuntimeError:
:raise イベントのためのイベントフックの外側で実行した場合に発生します。


trace = TracePoint.new(:raise) do |tp|
  tp.raised_exception # => #<ZeroDivisionError: divided by 0>
end
trace.enable
begin
  0/0
rescue
end
return_value -> object[permalink][rdoc][edit]

メソッドやブロックの戻り値を返します。

[EXCEPTION] RuntimeError:
:return、:c_return、:b_return イベントのためのイベントフックの外側で実行した場合に発生します。


def foo(ret)
  ret
end
trace = TracePoint.new(:return) do |tp|
  p tp.return_value # => 1
end
trace.enable
foo 1
self -> object[permalink][rdoc][edit]

イベントを発生させたオブジェクトを返します。

以下のようにする事で同じ値を取得できます。



trace.binding.eval('self')

[SEE_ALSO] TracePoint#binding