Как получить объект трассировки стека в Ruby? - PullRequest
56 голосов
/ 30 сентября 2010

Мне нужно получить объект трассировки стека в Ruby; не печатать его, просто заставить его сделать некоторую запись и сброс для последующего анализа. Это возможно? Как?

Ответы [ 6 ]

79 голосов
/ 30 сентября 2010

Для этого вы можете использовать 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"]
30 голосов
/ 31 июля 2013

Попробуйте

Thread.current.backtrace.join("\n")
12 голосов
/ 30 сентября 2010

Попробуйте 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
7 голосов
/ 14 января 2015

Для Ruby 2.0+ вы можете использовать Kernel#caller_locations.По сути, это то же самое, что и Kernel#caller (описано в ответе Свена Кошничке ), за исключением того, что вместо возврата массива строк он возвращает массив Thread::Backtrace::Location объектов.Thread::Backtrace::Location предоставляет такие методы, как path, lineno и base_label, которые могут быть полезны, когда вам необходим доступ к конкретным сведениям отрассировка стека, а не просто необработанная строка.

из документов :

caller_locations (начало = 1, длина = ноль) → массив или ноль

caller_locations (range) → array or nil

Возвращает текущий стек выполнения - массив, содержащий объекты местоположения обратной трассировки.

См. Thread::Backtrace::Location длядополнительная информация.

Необязательный параметр start определяет количество пропускаемых начальных записей стека в верхней части стека.

Второй необязательный параметр length может использоваться для ограничения количества записей.возвращаются из стека.

Возвращает nil, если start больше размера текущего стека выполнения.

При желании вы можете передать диапазон, который будет возвращать массив, содержащийзаписи в указанном диапазоне.

СШАпример ge:

def a
  caller_locations(0)
end
def b
  a
end
def c
  b
end

c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
3 голосов
/ 14 февраля 2017
Thread.current.backtrace

Это даст вам массив, который содержит все строки, которые вы можете получить в любой нормальной трассировке.

2 голосов
/ 19 ноября 2011

Вы можете создать свой собственный, если хотите.Как показано в Eloquent Ruby Рассом Олсеном:

# 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)
...