2

快速查询:Java 程序员将如何理解以下 Ruby 语句:

rescue ErrorType1, ErrorType2 => ex

也就是说,我想明确地在它周围加上括号/括号。那么,是吗?

rescue(ErrorType1, {ErrorType2 => ex})

或者,

rescue({[ErrorType1, ErrorType2] => ex})

或者是其他东西...

4

3 回答 3

4

关于语法:

rescue ErrorType1, ErrorType2 => ex

请注意以下事项:

  1. 不涉及哈希
  2. 'rescue' 不是方法,你甚至不能写成 rescue(ErrorType1, ErrorType2 => ex)
  3. Ruby 将对引发的关联异常的引用放入全局变量 $!。
  4. 在上面的表格中,'rescue' 有一个特殊的参数,你可以在其中给出一个局部变量的名称来接收匹配的异常,这比使用 $! 更具可读性。

现在,再次查看语法...

于 2013-10-05T11:25:54.843 回答
2

rescue是具有自己语法的控制结构,它不是方法调用,因此您的第二个和第三个代码块是无效的语法,您没有传递任何参数。

rescue <exception-class1>[, <exception-class2>] => <a variable to assign the exception to>

因此,在执行此操作时rescue TypeError, StandardError => my_exception,它将捕获引发的任何TypeError异常StandardError并将其分配给my_exception局部变量。

我推荐最近翻译的Ruby Hacking Guide(搜索“rescue”)。

于 2013-10-05T10:42:43.273 回答
1

看下面的代码:

begin
    a=1/0
rescue => e
    p e.class
    p defined?(e)
end
# >> ZeroDivisionError
# >> "local-variable"

Wheree是该异常处理块的局部变量。在 Ruby 中,局部变量是使用赋值操作创建的,但在异常处理的情况下,对当前引发的异常的引用使用哈希 Rocket( =>) 分配给局部变量 e,而不是=. 这是按照设计。不要认为它是一个Hash

在 Ruby 中,我们使用一个或多个救援子句来告诉 Ruby 我们要处理的异常类型。如果您编写一个没有参数列表的救援子句,则参数默认为StandardError. 每个救援子句可以指定要捕获的多个异常。在每个救援子句的末尾,您可以为 Ruby 提供一个局部变量的名称以接收匹配的异常。救援子句的参数也可以是返回异常类的任意表达式(包括方法调用)。如果我们使用不带参数的 raise,它会重新引发异常。处理异常

在您的三个代码中,只有rescue ErrorType1, ErrorType2 => ex. 其他人会给你语法错误。

层次结构(部分):

StandardError
   |
  IndexError
      |
     KeyError

您可以按任何顺序将错误类名称指定为rescue列表的参数。在运行时 ruby​​ 将从列表中选择正确的类。看下面的代码:

begin
    a = {}
    a.fetch(:b)
rescue StandardError,KeyError,IndexError => e
    p e.class
end
# >> KeyError

begin
    a = {}
    a.fetch(:b)
rescue KeyError,StandardError,IndexError => e
    p e.class
end
# >> KeyError

如果你认为,你会在运行时告诉 Ruby 解释器,首先使用参数列表中的括号匹配哪个,Ruby不允许这样做,作为回报,它会向你抛出语法错误。下面也一样:

begin
    a = {}
    a.fetch(:b)
rescue StandardError => e1
    p e1.class
rescue IndexError => e2
    p e2.class
rescue KeyError => e3
    p e3.class
end
# >> KeyError

注意:如果我们想捕获更多的异常类,我们可以将它们写成一行。当我们想以不同的方式处理不同的错误时,我们可以指定几个rescue子句。红宝石黑客指南

于 2013-10-05T10:42:50.027 回答