我有一些代码需要在ruby中拯救多种类型的异常:

begin
  a = rand
  if a > 0.5
    raise FooException
  else
    raise BarException
  end
rescue FooException, BarException
  puts "rescued!"
end

我想做的是以某种方式存储我想在某个地方救援的异常类型列表,并将这些类型传递给救援子句:

EXCEPTIONS = [FooException, BarException]

然后:

rescue EXCEPTIONS

这是可能的吗?如果没有一些真正的黑客呼叫eval,这是可能的吗?我不抱希望,因为当我try 上述方法时,我看到的是TypeError: class or module required for rescue clause.

推荐答案

可以使用splat运算符*的array.

EXCEPTIONS = [FooException, BarException]

begin
  a = rand
  if a > 0.5
    raise FooException
  else
    raise BarException
  end
rescue *EXCEPTIONS
  puts "rescued!"
end

如果要像上面那样为数组使用常量(带EXCEPTIONS),请注意不能在定义中定义它,而且如果在其他类中定义它,则必须使用其名称空间引用它.实际上,它不一定是常数.


Splat Operator

splat运算符*在其位置"解压"数组,以便

rescue *EXCEPTIONS

意思和

rescue FooException, BarException

您还可以在数组文本中使用它作为

[BazException, *EXCEPTIONS, BangExcepion]

这和

[BazException, FooException, BarException, BangExcepion]

或者处于争论的立场

method(BazException, *EXCEPTIONS, BangExcepion)

也就是说

method(BazException, FooException, BarException, BangExcepion)

[]inflating 为真空:

[a, *[], b] # => [a, b]

ruby 1.8和ruby 1.9之间的一个区别是nil.

[a, *nil, b] # => [a, b]       (ruby 1.9)
[a, *nil, b] # => [a, nil, b]  (ruby 1.8)

对定义了to_a的对象要小心,因为在这种情况下,to_a将被应用:

[a, *{k: :v}, b] # => [a, [:k, :v], b]

对于其他类型的对象,它会返回自身.

[1, *2, 3] # => [1, 2, 3]

Ruby相关问答推荐

根据部分已知值判断数组内容的简洁 Rubyist 方法是什么?

环绕分隔线,保留第一列,最小最终长度

如何使用正则表达式在字符串中查找特定匹配项

RVM 和 OpenSSL 的问题

Procs的绑定

ruby 中的魔术注释(#Encoding: utf-8)是如何工作的?

Ruby 相当于 Groovy 的 Elvis (?:) 运算符?

为什么我们要在 Ruby 的类中放置一个模块?

在单个 node 上使用 XPath 返回所有 node 中的元素

为什么 Ruby 使用 respond_to?而不是 responds_to?

Ruby 中的 method_missing trap

获取Ruby中数组的差异

判断是否在 SASS 中定义了变量

Ruby 中的=~运算符是什么?

我安装了一个 gem,但 require 'gemname' 不起作用.为什么?

常见的 Ruby 习语

等号 ('=') 放在方法定义中的方法名称之后有什么作用?

在 Ruby 中解析制表符分隔文件的最佳方法是什么?

如何在遍历数组时使用 Array#delete?

如何在 Ubuntu 12.04 上正确安装 ruby​​ 2.0.0?