класс TracePoint
Класс, предоставляющий функциональность Kernel#set_trace_func в хорошо структурированном объектно-ориентированном API.
Пример
Используйте TracePoint, чтобы собирать информацию именно об исключениях:
trace = TracePoint.new(:raise) do |tp| p [tp.lineno, tp.event, tp.raised_exception] end #=> #<TracePoint:disabled> trace.enable #=> false 0 / 0 #=> [5, :raise, #<ZeroDivisionError: divided by 0>]
События
Если не указать типы событий, которые нужно отслеживать, TracePoint будет включать все доступные события.
Примечание: Не полагайтесь на текущий набор событий, поскольку этот список может измениться. Вместо этого рекомендуется указать типы событий, которые вы хотите использовать.
Чтобы отфильтровать отслеживаемые события, можно передать любое количество следующих значений в качестве events:
:line-
Выполнение выражения или инструкции на новой строке.
:class-
Начало определения класса или модуля.
:end-
Завершение определения класса или модуля.
:call-
Вызов метода Ruby.
:return-
Возврат из метода Ruby.
:c_call-
Вызов подпрограммы на языке C.
:c_return-
Возврат из подпрограммы на языке C.
:raise-
Генерация исключения.
:rescue-
Перехват исключения.
:b_call-
Хук события при входе в блок.
:b_return-
Хук события при завершении блока.
:a_call-
Хук события для всех вызовов (
call,b_callиc_call). :a_return-
Хук события для всех возвратов (
return,b_returnиc_return). :thread_begin-
Хук события при запуске потока.
:thread_end-
Хук события при завершении потока.
:fiber_switch-
Хук события при переключении волокна.
:script_compiled-
Скомпилирован новый код Ruby (с помощью
eval,loadилиrequire).
Открытые методы класса
# File trace_point.rb, line 200 def self.allow_reentry Primitive.attr! :use_block Primitive.tracepoint_allow_reentry end
Как правило, пока выполняется обратный вызов TracePoint, другие зарегистрированные обратные вызовы не вызываются, чтобы избежать путаницы из-за повторного входа. Этот метод разрешает повторный вход в заданном блоке. Используйте его осторожно, чтобы избежать бесконечного вызова обратного вызова.
Если вызвать этот метод, когда повторный вход уже разрешён, будет возбуждено исключение RuntimeError.
Пример:
# Without reentry
# ---------------
line_handler = TracePoint.new(:line) do |tp|
next if tp.path != __FILE__ # Only works in this file
puts "Line handler"
binding.eval("class C; end")
end.enable
class_handler = TracePoint.new(:class) do |tp|
puts "Class handler"
end.enable
class B
end
# This script will print "Class handler" only once: when inside the :line
# handler, all other handlers are ignored.
# With reentry
# ------------
line_handler = TracePoint.new(:line) do |tp|
next if tp.path != __FILE__ # Only works in this file
next if (__LINE__..__LINE__+3).cover?(tp.lineno) # Prevent infinite calls
puts "Line handler"
TracePoint.allow_reentry { binding.eval("class C; end") }
end.enable
class_handler = TracePoint.new(:class) do |tp|
puts "Class handler"
end.enable
class B
end
# This will print "Class handler" twice: inside the allow_reentry block in the :line
# handler, other handlers are enabled.
Обратите внимание, что пример показывает основной эффект метода, однако на практике он используется при отладке библиотек, которым иногда необходимо, чтобы хуки других библиотек не зависели от того, что отладчик находится внутри обработчика точки трассировки. В этом случае следует принять меры против бесконечной рекурсии (обратите внимание: нам пришлось отфильтровать вызовы самого обработчика в обработчике :line, иначе он вызывал бы себя бесконечно).
# File trace_point.rb, line 96 def self.new(*events) Primitive.attr! :use_block Primitive.tracepoint_new_s(events) end
Возвращает новый объект TracePoint, по умолчанию отключённый.
Чтобы активировать объект TracePoint, используйте TracePoint#enable:
trace = TracePoint.new(:call) do |tp| p [tp.lineno, tp.defined_class, tp.method_id, tp.event] end #=> #<TracePoint:disabled> trace.enable #=> false puts "Hello, TracePoint!" # ... # [48, IRB::Notifier::AbstractNotifier, :printf, :call] # ...
Чтобы отключить трассировку, используйте TracePoint#disable.
trace.disable
Список возможных событий и дополнительную информацию см. в разделе События в TracePoint.
Необходимо передать блок, иначе будет возбуждено исключение ArgumentError.
Если метод трассировки не поддерживается для заданного фильтра событий, будет возбуждено исключение 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)
Доступ из других ракторов, потоков или волокон запрещён. Объекты TracePoint активны в пределах отдельного рактора, поэтому включение TracePoint в одном ракторе не повлияет на другие рактора.
# File trace_point.rb, line 119 def self.stat Primitive.tracepoint_stat_s end
Возвращает внутреннюю информацию об TracePoint.
Содержимое возвращаемого значения зависит от реализации и может измениться в будущем.
Этот метод предназначен только для отладки самого TracePoint.
# File trace_point.rb, line 134 def self.trace(*events) Primitive.attr! :use_block Primitive.tracepoint_trace_s(events) end
Вспомогательный метод для TracePoint.new, который автоматически активирует трассировку.
trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] }
#=> #<TracePoint:enabled>
trace.enabled? #=> true
Открытые методы экземпляра
# File trace_point.rb, line 383 def binding Primitive.tracepoint_attr_binding end
Возвращает объект привязки, созданный для события.
Обратите внимание: для событий :c_call и :c_return метод возвращает nil, поскольку сами методы C не имеют привязок.
# File trace_point.rb, line 339 def callee_id Primitive.tracepoint_attr_callee_id end
Возвращает имя вызываемого метода.
# File trace_point.rb, line 375 def defined_class Primitive.tracepoint_attr_defined_class end
Возвращает класс или модуль вызываемого метода.
class C; def foo; end; end trace = TracePoint.new(:call) do |tp| p tp.defined_class #=> C end.enable do C.new.foo end
Если метод определён модулем, возвращается этот модуль.
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
Примечание: defined_class возвращает синглтон-класс.
Шестой параметр блока метода Kernel#set_trace_func передаёт исходный класс, связанный синглтон-классом.
В этом заключается различие между Kernel#set_trace_func и TracePoint.
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
# File trace_point.rb, line 297 def disable Primitive.attr! :use_block Primitive.tracepoint_disable_m end
Отключает трассировку.
Возвращает true, если трассировка была включена. Возвращает false, если трассировка была отключена.
trace.enabled? #=> true trace.disable #=> true (previous status) trace.enabled? #=> false trace.disable #=> false
Если передан блок, трассировка будет отключена только на время выполнения блока.
trace.enabled? #=> true trace.disable do trace.enabled? # Only disabled for this block end trace.enabled? #=> true
Примечание: внутри блока нельзя обращаться к хукам событий.
trace.disable { p tp.lineno }
#=> RuntimeError: access from outside
# File trace_point.rb, line 261 def enable(target: nil, target_line: nil, target_thread: :default) Primitive.attr! :use_block Primitive.tracepoint_enable_m(target, target_line, target_thread) end
Включает трассировку.
Возвращает true, если трассировка была включена. Возвращает false, если трассировка была отключена.
trace.enabled? #=> false
trace.enable #=> false (previous state)
# trace is enabled
trace.enabled? #=> true
trace.enable #=> true (previous state)
# trace is still enabled
Если передан блок, трассировка будет включена только на время его выполнения. Если и target, и target_line равны nil, а блок передан, для target_thread будет использоваться текущий поток.
trace.enabled? #=> false trace.enable do trace.enabled? # Only enabled for this block and thread end trace.enabled? #=> false
Параметры target, target_line и target_thread используются, чтобы ограничить трассировку указанными объектами кода. target должен быть объектом кода, для которого RubyVM::InstructionSequence.of вернёт последовательность инструкций.
t = TracePoint.new(:line) { |tp| p tp }
def m1
p 1
end
def m2
p 2
end
t.enable(target: method(:m1))
m1
# Prints #<TracePoint:line test.rb:4 in `m1'>
m2
# Prints nothing
Примечание: внутри блока enable нельзя обращаться к хукам событий.
trace.enable { p tp.lineno }
#=> RuntimeError: access from outside
# File trace_point.rb, line 306 def enabled? Primitive.tracepoint_enabled_p end
Возвращает текущее состояние трассировки.
# File trace_point.rb, line 409 def eval_script Primitive.tracepoint_attr_eval_script end
Возвращает скомпилированный исходный код (String) из методов eval для события :script_compiled. Если код загружен из файла, возвращает nil.
# File trace_point.rb, line 313 def event Primitive.tracepoint_attr_event end
Возвращает тип события.
Дополнительную информацию см. в разделе События в TracePoint.
# File trace_point.rb, line 106 def inspect Primitive.tracepoint_inspect end
Возвращает строку с понятным человеку описанием состояния TracePoint.
# File trace_point.rb, line 417 def instruction_sequence Primitive.tracepoint_attr_instruction_sequence end
Возвращает скомпилированную последовательность инструкций, представленную экземпляром RubyVM::InstructionSequence для события :script_compiled.
Обратите внимание, что этот метод предназначен только для CRuby.
# File trace_point.rb, line 318 def lineno Primitive.tracepoint_attr_lineno end
Возвращает номер строки, в которой произошло событие.
# File trace_point.rb, line 334 def method_id Primitive.tracepoint_attr_method_id end
Возвращает имя, указанное при определении вызываемого метода.
# File trace_point.rb, line 329 def parameters Primitive.tracepoint_attr_parameters end
Возвращает определения параметров метода или блока, к которому относится текущий хук. Формат такой же, как у Method#parameters.
# File trace_point.rb, line 323 def path Primitive.tracepoint_attr_path end
Возвращает путь к выполняемому файлу.
# File trace_point.rb, line 403 def raised_exception Primitive.tracepoint_attr_raised_exception end
Возвращает исключение, возбужденное при событии :raise или перехваченное при событии :rescue.
# File trace_point.rb, line 398 def return_value Primitive.tracepoint_attr_return_value end
Возвращает значение, возвращённое при событиях :return, :c_return и :b_return.
# File trace_point.rb, line 393 def self Primitive.tracepoint_attr_self end
Возвращает объект трассировки во время события.
Результат аналогичен следующему, однако для событий :c_call и :c_return возвращается правильный объект (получатель метода):
trace.binding.eval('self')
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.