40

我试图弄清楚如何挽救eval()在 Ruby 1.8.6 中编写代码时出现的语法错误。

我期望以下 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 中的某个地方被救出,而我没有机会自己处理它。

任何人都知道如何获得我想要的行为(即,让我的“救援”子句从“评估”中捕获错误)?

4

2 回答 2

50

布伦特已经得到了一个可行的答案,但我建议从你可以逃脱的最小的例外中拯救出来。这可以确保您不会意外吞食您不想要的东西。

因此,

begin
  puts eval(good_str)
  puts eval(bad_str)
rescue SyntaxError => se
  puts 'RESCUED!'
end
于 2009-02-12T19:47:03.977 回答
45

嗯,这很容易...

事实证明,默认情况下,“rescue”语句不会捕获所有异常,而只会捕获 StandardError 的子类。SyntaxError 是 StandardError 的兄弟/表亲,而不是它的子类,因此除非明确告知,否则救援语句不会捕获它。

要让救援块捕获所有异常,您需要将代码更改为以下内容:

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

注意“rescue”行的变化,从“rescue => exc”到“rescue Exception => exc”。

现在,当你运行代码时,你会得到想要的结果:

2
RESCUED!
于 2009-02-12T19:25:42.513 回答