2009-02-12 55 views
36

我想弄清楚如何解決在Ruby 1.8.6中編寫代碼時出現的語法錯誤。如何在Ruby中拯救eval?

我希望下面的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 

產生以下結果在運行時:

2 
RESCUED! 

相反,我得到的是:

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

看樣子eval方法引發的SyntaxError在eval中的某處被救出,而沒有給我一個機會自己處理它。

任何人都有任何想法如何獲得我想要的行爲(即,我的'救援'條款從'eval'捕獲錯誤)?

回答

41

嗯,這很容易...

事實證明,在默認情況下,「救市」說法不趕所有例外,但只有那些StandardError的子類。 SyntaxError是StandardError的兄弟/表親,不是它的子類,所以除非明確告知,否則rescue語句不捕獲它。

要讓救援塊捕獲所有例外,您需要將代碼更改爲以下:

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

注意,在「救市」路線,以改變從「救市=> EXC」 「救援例外=> exc」。

現在,當你運行代碼,你得到想要的結果:

2 
RESCUED! 
+0

請看到這一點:http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby – gamov 2014-09-23 04:53:58

45

布倫特已經得到了一個answer that works,但我建議從最小的一組異常,你可以逃脫的搶救。這確保你不會意外地吞噬你不想要的東西。

因此,

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

這是很好的建議。例如,拯救Exception而不是SyntaxError會阻止你用ctrl-C中斷你的進程。 – 2009-02-12 23:10:20