在ruby异常中捕获行号

时间:2020-03-06 14:34:54  来源:igfitidea点击:

考虑以下红宝石代码

test.rb:

begin

  puts
  thisFunctionDoesNotExist
  x = 1+1
rescue Exception => e
  p e
end

出于调试目的,我希望救援块知道该文件的第4行中发生了错误。有没有这样做的干净方法?

解决方案

p e.backtrace

我在没有资源的IRB会议上运行了该报告,但仍提供了相关信息。

=> ["(irb):11:in `foo'", 
    "(irb):17:in `irb_binding'", 
     "/usr/lib64/ruby/1.8/irb/workspace.rb:52:in `irb_binding'", 
     "/usr/lib64/ruby/1.8/irb/workspace.rb:52"]

如果我们想很好地解析回溯,可以使用以下正则表达式:

p x.backtrace.map{ |x|   
     x.match(/^(.+?):(\d+)(|:in `(.+)')$/); 
    [,,] 
}

[
  ["(irb)", "11", "foo"], 
  ["(irb)", "48", "irb_binding"], 
  ["/usr/lib64/ruby/1.8/irb/workspace.rb", "52", "irb_binding"], 
  ["/usr/lib64/ruby/1.8/irb/workspace.rb", "52", nil]
]

(正则表达式/应该/可以防止函数名或者目录/文件名中的怪异字符)
(如果我们想知道foo的来源,我做了一个def来捕获异常:

>>def foo
>>  thisFunctionDoesNotExist
>> rescue Exception => e 
>>   return e 
>>end     
>>x = foo 
>>x.backtrace

我们可以从Exception对象访问回溯。要查看整个回溯,请执行以下操作:

p e.backtrace

它将包含用于调用堆栈的文件和行号的数组。对于一个简单的脚本(如问题中的脚本),它将只包含一行。

["/Users/dan/Desktop/x.rb:4"]

如果需要行号,则可以检查回溯的第一行,并在冒号之后提取值。

p e.backtrace[0].split(":").last

在Ruby 1.9.3中,我们可能不仅可以使用结构化,可靠和简单的方式访问这些信息,而且无需使用正则表达式来剪切字符串。

基本思想是引入一个调用框架对象,该对象可以访问有关调用堆栈的信息。

参见http://wiki.github.com/rocky/rb-threadframe/,可惜需要修补Ruby 1.9. 在RubyKaigi 2010(2010年8月下旬)中,计划召开会议讨论将框架对象引入Ruby。

鉴于此,最早可能发生在Ruby 1.9.3中。

在这个旧线程上投入我的0.02美元,这是一个维护所有原始数据的简单解决方案:

print e.backtrace.join("\n")