Ruby 异常的语法

3

我希望你能帮助我翻译Ruby异常的语法。

我找到了这个例子:

begin
    puts "Running with b=#{ b }"
    exception_if(b)
    puts "After possible exception"
  rescue ArgumentError => e
    puts "An error occured: #{ e }!"
  ensure
    puts "Always excuted, no matter what."
  end

来源:维基图书

"ArgumentError"是要捕获的异常类型,rescue语句块中的"e"是引用变量吗?

我的理解是否正确?

后来我找到了这段代码,完全搞糊涂了:

begin
  @product = Product.find(params[:id])
rescue => e
  redirect_to root_path
end

箭头(=>)前的第一部分在哪里?

有人能解释一下这两个片段的含义吗?


2
你说得对,第一个情况将匹配任何“raise ArgumentError”,而“e”是错误,这使您可以获取回溯信息等。在第二种情况下,没有类型的“rescue”将拯救“StandardError”,它是大多数“正常”的可处理应用程序错误(不像其他一些语言中的“Exception”)。 - rmlockerd
这个回答解决了你的问题吗?为什么在Ruby中使用“rescue Exception => e”是不好的编程风格? - builder-7000
1
@sergio 抱歉,它并没有解决我的问题。我的问题更多地涉及一般语法及其可行的变化形式。主要是不同的变化形式让我感到困惑。尽管如此:这是一篇有趣的阅读。谢谢你。 - cluster1
2个回答

2

你对第一个片段的解释基本正确。但是你提到的“引用变量”不是很清楚。

=>箭头后面的标识符将绑定到被救援的异常,并在rescue块中生效。

第二个片段基本上省略了被救援的异常类,这意味着它使用默认值。如果您没有指定异常类,它将使用StandardError作为默认值,并从所有是StandardError实例的异常中进行救援。

注意:这并不会救援所有错误!它只会救援是StandardError实例的异常,但不会救援所有Exception的实例。

例如,SystemStackError直接继承自Exception,而不是StandardError的子类,因此不会被第二个片段所救援。

通常,不继承自StandardError的异常是您无法恢复的异常,例如内存耗尽或VM内部数据结构的损坏。您应该尽可能地指定异常,只救援您实际可以处理的异常 - 理想情况下,您应该为自己的代码创建自定义异常类,并仅救援那些异常。


2

编辑:在控制台中,第二段代码片段正在捕获StandardError 实例的错误

begin
  raise NoMethodError
rescue => e
  puts e.inspect
end
#<NoMethodError: NoMethodError>

异常对象被分配给变量e。这也可以理解为
rescue StandardError => e

首先的代码段最初是针对一个特定错误进行rescue操作,如果发生其他类型的错误,则始终执行ensure块,然后退出该方法。

通常情况下,您应该仅捕获程序可以从中恢复的异常。如果程序遇到未知异常,请崩溃并修复问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接