class 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-
Хук события при переключении fiber.
:script_compiled-
Скомпилирован новый код Ruby (с помощью
eval,loadилиrequire).
Общедоступные методы класса
# File trace_point.rb, line 198 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 94 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)
Доступ из других потоков также запрещён.
# File trace_point.rb, line 117 def self.stat Primitive.tracepoint_stat_s end
Возвращает внутреннюю информацию о TracePoint.
Содержимое возвращаемого значения зависит от реализации и может измениться в будущем.
Этот метод предназначен только для отладки самого TracePoint.
# File trace_point.rb, line 132 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 381 def binding Primitive.tracepoint_attr_binding end
Возвращает объект binding, созданный для события.
Обратите внимание: для событий :c_call и :c_return метод возвращает nil, поскольку у самих методов C нет объектов binding.
# File trace_point.rb, line 337 def callee_id Primitive.tracepoint_attr_callee_id end
Возвращает имя вызываемого метода.
# File trace_point.rb, line 373 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 возвращает singleton-класс.
Шестой параметр блока в Kernel#set_trace_func передаёт исходный класс, связанный с singleton-классом.
Это различие между 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 295 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 259 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 304 def enabled? Primitive.tracepoint_enabled_p end
Возвращает текущее состояние трассировки.
# File trace_point.rb, line 407 def eval_script Primitive.tracepoint_attr_eval_script end
Возвращает скомпилированный исходный код (String) методов eval для события :script_compiled. Если код загружен из файла, возвращается nil.
# File trace_point.rb, line 311 def event Primitive.tracepoint_attr_event end
Возвращает тип события.
Дополнительную информацию см. в разделе «События» в TracePoint.
# File trace_point.rb, line 104 def inspect Primitive.tracepoint_inspect end
Возвращает строку с понятным человеку описанием состояния TracePoint.
# File trace_point.rb, line 415 def instruction_sequence Primitive.tracepoint_attr_instruction_sequence end
Возвращает скомпилированную последовательность инструкций, представленную экземпляром RubyVM::InstructionSequence, для события :script_compiled.
Обратите внимание, что этот метод специфичен для CRuby.
# File trace_point.rb, line 316 def lineno Primitive.tracepoint_attr_lineno end
Возвращает номер строки события.
# File trace_point.rb, line 332 def method_id Primitive.tracepoint_attr_method_id end
Возвращает имя метода в месте его определения.
# File trace_point.rb, line 327 def parameters Primitive.tracepoint_attr_parameters end
Возвращает определения параметров метода или блока, к которому относится текущий хук. Формат совпадает с форматом Method#parameters.
# File trace_point.rb, line 321 def path Primitive.tracepoint_attr_path end
Возвращает путь к выполняемому файлу.
# File trace_point.rb, line 401 def raised_exception Primitive.tracepoint_attr_raised_exception end
Возвращает исключение, возбужденное при событии :raise или перехваченное при событии :rescue.
# File trace_point.rb, line 396 def return_value Primitive.tracepoint_attr_return_value end
Возвращает значение, полученное при событиях :return, :c_return и :b_return.
# File trace_point.rb, line 391 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.