2009-02-12 6 views
36

Ich versuche herauszufinden, wie Syntaxfehler behoben werden, die auftreten, wenn Code in Ruby 1.8.6 eval().Wie man ein Eval in Ruby retten kann?

Ich würde den folgenden Ruby-Code erwarten:

#!/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 

das folgende Ergebnis zu erzeugen, wenn auszuführen:

2 
RESCUED! 

Statt dessen, was ich bekommen ist:

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

Es scheint, dass der SyntaxError, der durch die Eval-Methode ausgelöst wurde, irgendwo innerhalb des Evals gerettet wird, ohne mir eine Chance zu geben o handle es selbst.

Jeder hat eine Idee, wie man das Verhalten, das ich will (d. H. Für meine 'Rettung' Klausel, um den Fehler von der 'Eval' zu bekommen) bekommen?

Antwort

41

Nun, das war einfach ...

Es stellt sich heraus, dass standardmäßig die „Rettung“ Anweisung nicht alle Ausnahmen verfängt, sondern nur diejenigen, die Unterklassen von Standarderror. SyntaxError ist ein Geschwister/Cousin von StandardError, keine Unterklasse davon, daher erfasst die Rescue-Anweisung sie nicht, es sei denn, dies wird ausdrücklich angewiesen.

zur Rettung Block Capture alle Ausnahmen haben, müssen Sie die den Code ändern folgende:

#!/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 

Beachten Sie die Änderung in der "Rettung" Linie von "rescue => exc" zu "Ausnahme retten => exc".

Nun, wenn Sie den Code ausführen, erhalten Sie die gewünschten Ergebnisse:

2 
RESCUED! 
+0

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

45

Brent bereits ein answer that works bekam, aber ich empfehle von der kleinsten Menge von Ausnahmen Rettung man sich erlauben kann. Dies stellt sicher, dass Sie nicht versehentlich etwas verschlingen, was Sie nicht sein wollen.

So

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

Das ist ein guter Rat. Wenn Sie beispielsweise Exception statt SyntaxError retten, können Sie Ihren Prozess nicht mit einer Ctrl-C unterbrechen. –

+0

Ich bin überrascht, dass dies nicht mehr als Best Practice aufgegriffen hat. – tamouse