2008-09-23 12 views
39

Consideremos el siguiente código de rubíLa captura de números de línea en excepciones rubí

test.rb:

begin 

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

Para propósitos de depuración, me gustaría que el bloque de rescate saber que se produjo el error en la línea 4 del presente archivo. ¿Hay una manera limpia de hacer eso?

Respuesta

57
p e.backtrace 

me encontré en una sesión de IRB, que no tiene una fuente y todavía dio información relevante.

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

Si desea una traza muy bien analizada, la siguiente expresión regular puede ser útil:

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/debe/ser seguro contra caracteres extraños en los nombres de función o directorios/nombres de archivo) (Si usted se pregunta dónde camefrom foo, he hecho una definición para agarrar la excepción a cabo:.

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

puede acceder a la traza de un objeto excepción a ver todo el backtrace:

p e.backtrace 

Contendrá una matriz de archivos y números de línea para la pila de llamadas. Para un script simple como el de su pregunta, solo contendría una línea.

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

Si desea que el número de línea, se puede examinar la primera línea de la traza, y extraer el valor después de los dos puntos.

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

'.last' obtiene el nombre del método. El número de línea es un elemento antes de eso. – kixorz

0

Es posible que en Ruby 1.9.3 usted será capaz de obtener acceso a esta información no sólo de una manera más estructurada, fiable y sencilla sin necesidad de utilizar expresiones regulares para cortar cuerdas.

La idea básica es introducir un objeto de marco de llamada que da acceso a información sobre la pila de llamadas.

Ver http://wiki.github.com/rocky/rb-threadframe/, que alas, requiere parchear Ruby 1.9. En RubyKaigi 2010 (finales de agosto de 2010) está programada una reunión para discutir la introducción de un objeto marco en Ruby.

Dado esto, lo primero que podría pasar es en Ruby 1.9.3.

6

Lanzar mi $ 0,02 en este viejo thread-- aquí es una solución simple que mantiene todos los datos originales:

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

Por lo general, la traza contiene una gran cantidad de líneas de gemas externos Es mucho más conveniente para ver sólo las líneas relacionadas con el proyecto en sí

Mi sugerencia es filtrar la traza por el nombre de la carpeta de proyecto

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

Y luego puede analizar líneas filtradas para extraer los números de línea como se sugiere en otras respuestas.

Cuestiones relacionadas