我需要在Ruby中获取一个堆栈跟踪对象,而不是将其打印出来,只是为了进行一些记录和转储以供后续分析。这可能吗?怎么做?
我需要在Ruby中获取一个堆栈跟踪对象,而不是将其打印出来,只是为了进行一些记录和转储以供后续分析。这可能吗?怎么做?
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"]
尝试
Thread.current.backtrace.join("\n")
尝试使用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
Kernel#caller_locations
。它基本上与Kernel#caller
相同(在Sven Koschnicke的答案中有介绍),只是它返回一个Thread :: Backtrace :: Location
对象数组,而不是字符串数组。Thread :: Backtrace :: Location
提供了一些方法,例如path
、lineno
和base_label
,当您需要访问关于堆栈跟踪的特定细节而不仅仅是原始字符串时,这些方法可能很有用。使用示例:caller_locations(start=1, length=nil) → array or nil
caller_locations(range) → array or nil
返回包含回溯位置对象的数组,表示当前执行堆栈。
有关详细信息,请参见
Thread :: Backtrace :: Location
。可选的 start 参数确定要从堆栈顶部忽略的初始堆栈条目数。
第二个可选的
length
参数可用于限制从堆栈中返回的条目数量。如果 start 大于当前执行堆栈的大小,则返回
nil
。还可以传递范围,它将返回包含指定范围内条目的数组。
def a
caller_locations(0)
end
def b
a
end
def c
b
end
c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
Thread.current.backtrace
如果你愿意,你也可以创建你自己的模块。正如Russ Olsen在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)