it-swarm.com.de

Fangen von Zeilennummern in Ruby-Ausnahmen

Betrachten Sie den folgenden Ruby-Code

test.rb:

begin

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

Zu Debugging-Zwecken möchte ich, dass der Rettungsblock weiß, dass der Fehler in Zeile 4 dieser Datei aufgetreten ist. Gibt es eine saubere Möglichkeit, das zu tun?

44
anshul
p e.backtrace 

Ich habe es in einer IRB-Sitzung ausgeführt, die keine Quelle hat und dennoch relevante Informationen enthält.

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

Wenn Sie eine schön geparste Rückverfolgung wünschen, kann der folgende reguläre Ausdruck nützlich sein:

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/sollte/sollte vor seltsamen Zeichen in Funktionsnamen oder Verzeichnissen/Dateinamen sicher sein) (Wenn Sie sich fragen, wo foo camefrom, habe ich einen Def gemacht, um die Ausnahme herauszuholen:

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

Sie können von einem Exception-Objekt aus auf die Rückverfolgung zugreifen. So zeigen Sie den gesamten Backtrace an:

p e.backtrace

Es enthält eine Reihe von Dateien und Zeilennummern für den Aufrufstapel. Bei einem einfachen Skript wie dem in Ihrer Frage würde es nur eine Zeile enthalten.

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

Wenn Sie die Zeilennummer möchten, können Sie die erste Zeile der Rückverfolgung untersuchen und den Wert nach dem Doppelpunkt extrahieren.

p e.backtrace[0].split(":").last
20
dan-manges

Wirf meine $ 0.02 in diesen alten Thread - hier ist eine einfache Lösung, die alle Originaldaten beibehält:

print e.backtrace.join("\n")
6
John Bachir

Normalerweise enthält der Backtrace viele Zeilen aus externen Edelsteinen. Es ist viel praktischer, nur Zeilen zu sehen, die sich auf das Projekt selbst beziehen

Mein Vorschlag ist, die Rückverfolgung nach dem Namen des Projektordners zu filtern

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

Und dann können Sie gefilterte Zeilen analysieren, um Zeilennummern zu extrahieren, wie in anderen Antworten vorgeschlagen.

5
Serge Seletskyy

Es ist möglich, dass Sie in Ruby 1.9.3 nicht nur strukturierter, zuverlässiger und einfacher auf diese Informationen zugreifen können, ohne reguläre Ausdrücke zum Ausschneiden von Zeichenfolgen zu verwenden.

Die Grundidee besteht darin, ein Call-Frame-Objekt einzuführen, das den Zugriff auf Informationen über den Call-Stack ermöglicht.

Siehe http://wiki.github.com/rocky/rb-threadframe/ , für das leider ein Patch für Ruby 1.9 erforderlich ist. In RubyKaigi 2010 (Ende August 2010) ist eine Besprechung geplant, in der die Einführung eines Frame-Objekts in Ruby besprochen wird.

Aus diesem Grund ist dies in Ruby 1.9.3 am frühesten möglich.

0
rocky