Spec-Zone.ru › Ruby 3.2

класс TracePoint

Родитель:
Объект

Класс документа: 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

выброс исключения

: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)

Публичные методы класса

allow_reentry { block } Показать исходный код
# File trace_point.rb, line 199
def self.allow_reentry
  Primitive.tracepoint_allow_reentry
end

В общем случае, пока обратный вызов TracePoint выполняется, другие зарегистрированные обратные вызовы не вызываются, чтобы избежать конфликтов из-за повторного входа. Этот метод разрешает повторный вход в заданном блоке. Этот метод следует использовать осторожно, иначе обратный вызов может быть вызван бесконечно.

Если этот метод вызывается, когда повторный вход уже разрешен, он генерирует исключение RuntimeError.

Пример:

# Without reentry
# ---------------

line_handler = TracePoint.new(:line) do |tp|
  next if tp.path != __FILE__ # only work 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 :line
# handler, all other handlers are ignored

# With reentry
# ------------

line_handler = TracePoint.new(:line) do |tp|
  next if tp.path != __FILE__ # only work in this file
  next if (__LINE__..__LINE__+3).cover?(tp.lineno) # don't be invoked from itself
  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 wil print "Class handler" twice: inside allow_reentry block in :line
# handler, other handlers are enabled.

Обратите внимание, что пример демонстрирует основной эффект метода, но его практическое использование заключается в отладке библиотек, которые иногда требуют, чтобы другие библиотечные обработчики не затрагивались отладчиком, находящимся внутри обработки точки трассировки. В этом случае следует принять меры против бесконечной рекурсии (обратите внимание, что нам потребовалось отфильтровать вызовы самого себя из обработчика :line, иначе он будет вызывать себя бесконечно).

new(*events) { |obj| block } → obj Показать исходный код
# File trace_point.rb, line 97
def self.new(*events)
  Primitive.tracepoint_new_s(events)
end

Возвращает новый объект 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)

Доступ из других потоков также запрещён.

stat → obj Показать исходный код
# File trace_point.rb, line 119
def self.stat
  Primitive.tracepoint_stat_s
end

Возвращает внутреннюю информацию о TracePoint.

Содержание возвращаемого значения зависит от реализации. Оно может быть изменено в будущем.

Этот метод предназначен только для отладки TracePoint само по себе.

trace(*events) { |obj| block } → obj Показать исходный код
# File trace_point.rb, line 134
def self.trace(*events)
  Primitive.tracepoint_trace_s(events)
end

Удобный метод для TracePoint.new, который автоматически активирует трассировку.

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

trace.enabled? #=> true

Общедоступные методы экземпляра

binding() Показать исходный код
# File trace_point.rb, line 383
def binding
  Primitive.tracepoint_attr_binding
end

Возвращает сгенерированный объект привязки из события.

Обратите внимание, что для событий c_call и c_return возвращаемая привязка — это привязка ближайшего Ruby-метода, вызывающего C-метод, так как у самих C-методов нет привязок.

callee_id() Показать исходный код
# File trace_point.rb, line 338
def callee_id
  Primitive.tracepoint_attr_callee_id
end

Возвращает имя вызываемого метода.

defined_class() Показать исходный код
# File trace_point.rb, line 374
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 возвращает синглтон-класс.

6-й параметр блока 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
disable → true или false Показать исходный код
disable { блок } → обект
# File trace_point.rb, line 297
def disable
  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
enable(target: nil, target_line: nil, target_thread: nil) → true или false Показать исходный код
enable(target: nil, target_line: nil, target_thread: :default) { блок } → обект
# File trace_point.rb, line 261
def enable(target: nil, target_line: nil, target_thread: :default)
  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
enabled? → true или false Показать исходный код
# File trace_point.rb, line 305
def enabled?
  Primitive.tracepoint_enabled_p
end

Текущий статус отслеживания

eval_script() Показать исходный код
# File trace_point.rb, line 409
def eval_script
  Primitive.tracepoint_attr_eval_script
end

Скомпилированный исходный код (String) для методов *eval в событии :script_compiled. Если загружено из файла, вернёт nil.

event() Показать исходный код
# File trace_point.rb, line 312
def event
  Primitive.tracepoint_attr_event
end

Тип события

См. События в TracePoint для получения дополнительной информации.

inspect → строка Показать исходный код
# File trace_point.rb, line 106
def inspect
  Primitive.tracepoint_inspect
end

Возвращает строку с удобочитаемым статусом TracePoint.

instruction_sequence() Показать исходный код
# File trace_point.rb, line 417
def instruction_sequence
  Primitive.tracepoint_attr_instruction_sequence
end

Скомпилированная последовательность инструкций, представленная экземпляром RubyVM::InstructionSequence в событии :script_compiled.

Обратите внимание, что этот метод специфичен для MRI.

lineno() Показать исходный код
# File trace_point.rb, line 317
def lineno
  Primitive.tracepoint_attr_lineno
end

Номер строки события

method_id() Показать исходный код
# File trace_point.rb, line 333
def method_id
  Primitive.tracepoint_attr_method_id
end

Возвращает имя метода в его определении.

parameters() Показать исходный код
# File trace_point.rb, line 328
def parameters
  Primitive.tracepoint_attr_parameters
end

Возвращает определение параметров метода или блока, к которому относится текущий обработчик. Формат аналогичен формату Method#parameters.

path() Показать исходный код
# File trace_point.rb, line 322
def path
  Primitive.tracepoint_attr_path
end

Путь к выполняемому файлу.

raised_exception() Показать исходный код
# File trace_point.rb, line 403
def raised_exception
  Primitive.tracepoint_attr_raised_exception
end

Значение исключения, выброшенного в событии :raise.

return_value() Показать исходный код
# File trace_point.rb, line 398
def return_value
  Primitive.tracepoint_attr_return_value
end

Возвращаемое значение в событиях :return, c_return, и b_return.

self() Показать исходный код
# File trace_point.rb, line 393
def self
  Primitive.tracepoint_attr_self
end

Возвращает объект отслеживания во время события.

То же самое, что и ниже, за исключением того, что оно возвращает правильный объект (получатель метода) для событий c_call и c_return:

trace.binding.eval('self')

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API