Подтвердить что ты не робот

Зачисление номеров строк в исключениях рубина

Рассмотрим следующий код ruby ​​

test.rb:

begin

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

В целях отладки я хотел бы, чтобы блок спасения знал, что ошибка произошла в строке 4 этого файла. Есть ли чистый способ сделать это?

4b9b3361

Ответ 1

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 `(.+)')$/); 
    [$1,$2,$4] 
}

[
  ["(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]
]

(Regex/должно/быть безопасным от странных символов в именах функций или каталогах/именах файлов) (Если вам интересно, откуда сработало foo, я решил сделать исключение:

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

Ответ 2

Вы можете получить доступ к backtrace из объекта Exception. Чтобы увидеть всю обратную трассировку:

p e.backtrace

Он будет содержать массив файлов и номеров строк для стека вызовов. Для простого script, подобного одному в вашем вопросе, он просто будет содержать одну строку.

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

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

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

Ответ 3

Бросив мои $0.02 в этот старый поток - вот простое решение, которое поддерживает все исходные данные:

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

Ответ 4

Обычно backtrace содержит много строк из внешних драгоценных камней Гораздо удобнее видеть только строки, связанные с самим проектом

Мое предложение состоит в том, чтобы отфильтровать backtrace по имени папки проекта

puts e.backtrace.select { |x| x.match(/HERE-IS-YOUR-PROJECT-FOLDER-NAME/) }

И затем вы можете проанализировать отфильтрованные строки для извлечения номеров строк, как это предлагается в других ответах.

Ответ 5

Возможно, что в Ruby 1.9.3 вы сможете получить доступ не только к этой информации более структурированным, надежным и простым способом, не используя регулярные выражения для вырезания строк.

Основная идея состоит в том, чтобы ввести объект кадра вызова, который предоставляет доступ к информации о стеке вызовов.

См. http://wiki.github.com/rocky/rb-threadframe/, который, увы, требует исправления Ruby 1.9. В RubyKaigi 2010 (конец августа 2010 года) планируется обсудить вопрос о введении объекта кадра в Ruby.

Учитывая это, самое раннее это может произойти в Ruby 1.9.3.