2009-02-12 65 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