Мне нужно получить объект трассировки стека в Ruby; не печатать его, просто чтобы заставить его сделать запись и сброс для последующего анализа. Это возможно? Как?
Как получить объект трассировки стека в Ruby?
Ответ 1
Вы можете использовать Kernel.caller для этого. Тот же метод используется при генерации трассировок стека для исключений.
Из документов:
def a(skip)
caller(skip)
end
def b(skip)
a(skip)
end
def c(skip)
b(skip)
end
c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
c(2) #=> ["prog:8:in `c'", "prog:12"]
c(3) #=> ["prog:13"]
Ответ 2
Попробуйте
Thread.current.backtrace.join("\n")
Ответ 3
Попробуйте error.backtrace:
# Returns any backtrace associated with the exception.
# The backtrace is an array of strings, each containing either ``filename:lineNo: in `method’’’ or ``filename:lineNo.’‘
def a
raise "boom"
end
def b
a()
end
begin
b()
rescue => detail
print detail.backtrace.join("\n")
end
дает:
prog.rb:2:in `a'
prog.rb:6:in `b'
prog.rb:10
Ответ 4
Для Ruby 2.0+ вы можете использовать Kernel#caller_locations
. Это по существу то же самое, что Kernel#caller
(см. ответ Sven Koschnicke), за исключением того, что вместо возврата массива строк он возвращает массив объектов Thread::Backtrace::Location
. Thread::Backtrace::Location
предоставляет такие методы, как path
, lineno
и base_label
, что может быть полезно, когда вам нужен доступ к конкретным сведениям о трассировке стека, а не только необработанная строка.
От документы:
caller_locations (start = 1, length = nil) → array или nil
caller_locations (диапазон) → массив или nil
Возвращает текущий стек выполнения - массив, содержащий обратную трассировку объектов местоположения.
Подробнее см.
Thread::Backtrace::Location
.Необязательный параметр запуска определяет количество начального стека записи, чтобы опустить из верхней части стека.
Второй необязательный параметр
length
может использоваться для ограничения количества записи возвращаются из стека.Возвращает
nil
, еслиstart
больше, чем размер текущего исполнения стек.Необязательно вы можете передать диапазон, который будет возвращать массив, содержащий записи в указанном диапазоне.
Пример использования:
def a
caller_locations(0)
end
def b
a
end
def c
b
end
c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
Ответ 5
Вы также можете создать свой собственный, если хотите. Как показано в "Красноречивом рубине" Руса Олсена:
# define a proc to use that will handle your trace
proc_object = proc do |event, file, line, id, binding, klass|
puts "#{event} in #{file}/#{line} #{id} #{klass}"
end
# tell Ruby to use your proc on traceable events
set_trace_func(proc_object)
Ответ 6
Thread.current.backtrace
Это даст вам массив, который содержит все строки, которые вы можете получить в любом обычном обратном направлении.