Spec-Zone.ru › Ruby 3.4

класс 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).

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

allow_reentry { block }
Исходный код
# 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, иначе бы это привело к бесконечному вызову самого себя).

new(*events) { |tp| block } → tp
Исходный код
# 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)

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

stat → obj
Исходный код
# File trace_point.rb, line 117
def self.stat
  Primitive.tracepoint_stat_s
end

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

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

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

trace(*events) { |tp| block } → obj
Исходный код
# 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

Методы публичного экземпляра

binding ()
Исходный код
# File trace_point.rb, line 381
def binding
  Primitive.tracepoint_attr_binding
end

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

Обратите внимание, что для событий :c_call и :c_return метод возвращает nil, так как у самих C-методов нет привязок.

callee_id ()
Исходный код
# File trace_point.rb, line 337
def callee_id
  Primitive.tracepoint_attr_callee_id
end

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

defined_class ()
Исходный код
# 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 возвращает единственный класс.

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

Возвращает текущий статус отслеживания.

eval_script ()
Исходный код
# File trace_point.rb, line 407
def eval_script
  Primitive.tracepoint_attr_eval_script
end

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

event ()
Исходный код
# File trace_point.rb, line 311
def event
  Primitive.tracepoint_attr_event
end

Возвращает тип события.

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

inspect → строка
Исходный код
# File trace_point.rb, line 104
def inspect
  Primitive.tracepoint_inspect
end

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

instruction_sequence ()
Исходный код
# File trace_point.rb, line 415
def instruction_sequence
  Primitive.tracepoint_attr_instruction_sequence
end

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

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

lineno ()
Исходный код
# File trace_point.rb, line 316
def lineno
  Primitive.tracepoint_attr_lineno
end

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

method_id ()
Исходный код
# File trace_point.rb, line 332
def method_id
  Primitive.tracepoint_attr_method_id
end

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

parameters ()
Исходный код
# File trace_point.rb, line 327
def parameters
  Primitive.tracepoint_attr_parameters
end

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

path ()
Исходный код
# File trace_point.rb, line 321
def path
  Primitive.tracepoint_attr_path
end

Возвращает путь к исполняемому файлу.

raised_exception ()
Исходный код
# File trace_point.rb, line 401
def raised_exception
  Primitive.tracepoint_attr_raised_exception
end

Возвращает исключение, поднятое в событии :raise или перехваченное в событии :rescue.

return_value ()
Исходный код
# File trace_point.rb, line 396
def return_value
  Primitive.tracepoint_attr_return_value
end

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

self ()
Исходный код
# File trace_point.rb, line 391
def self
  Primitive.tracepoint_attr_self
end

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

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

trace.binding.eval('self')

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

Spec-Zone.ru

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