2009-02-12 16 views
36

Estoy tratando de encontrar la forma de rescatar los errores de sintaxis que surgen cuando eval() ing código en Ruby 1.8.6.¿Cómo rescatar a un eval en Ruby?

que sería de esperar el siguiente código Ruby:

#!/usr/bin/ruby 

good_str = "(1+1)" 
bad_str = "(1+1" # syntax error: missing closing paren 

begin 
    puts eval(good_str) 
    puts eval(bad_str) 
rescue => exc 
    puts "RESCUED!" 
end 

para producir el siguiente resultado cuando se ejecuta:

2 
RESCUED! 

En su lugar, lo que consigo es:

2 
eval_rescue.rb:8: (eval):1: compile error (SyntaxError) 
(eval):1: syntax error, unexpected $end, expecting ')' 

Parece que el SyntaxError generado por el método eval está siendo rescatado en algún lugar dentro de la evaluación, sin darme la oportunidad de o manejarlo yo mismo.

¿Alguien tiene alguna idea de cómo obtener el comportamiento que quiero (es decir, para que mi cláusula de 'rescate' capte el error del 'eval')?

Respuesta

41

Bueno, eso fue fácil ...

Resulta que, por defecto, el "rescate" declaración de no coger todos excepciones, pero sólo aquellos que son subclases de StandardError. SyntaxError es un hermano/primo de StandardError, no una subclase de él, por lo que la instrucción de rescate no lo captura a menos que explícitamente se lo indique.

Para que la captura de bloques de rescate todos excepciones, es necesario cambiar el código a la siguiente:

#!/usr/bin/ruby 

good_str = "(1+1)" 
bad_str = "(1+1" # syntax error: missing closing paren 

begin 
    puts eval(good_str) 
    puts eval(bad_str) 
rescue Exception => exc 
    puts "RESCUED!" 
end 

nota el cambio en la línea de "rescate", de "rescate => exc" a "Excepción de rescate => exc".

Ahora, cuando se ejecuta el código, se obtiene los resultados deseados:

2 
RESCUED! 
+0

favor ver esto: http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby – gamov

45

Brent ya tiene un answer that works, pero recomiendo el rescate desde el más pequeño conjunto de excepciones que puede salir a. Esto asegura que no estés engullendo accidentalmente algo que no pretendes ser.

Por lo tanto,

begin 
    puts eval(good_str) 
    puts eval(bad_str) 
rescue SyntaxError => se 
    puts 'RESCUED!' 
end 
+6

Este es un buen consejo. Por ejemplo, rescatar Exception en lugar de SyntaxError evitará que interrumpa su proceso con un ctrl-C. –

+0

Me sorprende que esto no se haya contado más con una buena práctica. – tamouse

Cuestiones relacionadas