以DRY方式将多个错误类传递给ruby的救援条款
我有一些代码需要在ruby中拯救多种types的exception:
begin a = rand if a > 0.5 raise FooException else raise BarException end rescue FooException, BarException puts "rescued!" end
我想要做的是以某种方式存储我想要救援的exceptiontypes列表,并将这些types传递给rescue子句:
EXCEPTIONS = [FooException, BarException]
接着:
rescue EXCEPTIONS
这甚至是可能的,是否有可能没有一些真正的黑客调用eval
? 我没有希望,因为我看到TypeError: class or module required for rescue clause
当我尝试上述的TypeError: class or module required for rescue clause
。
您可以使用splat运算符*
的数组。
EXCEPTIONS = [FooException, BarException] begin a = rand if a > 0.5 raise FooException else raise BarException end rescue *EXCEPTIONS puts "rescued!" end
如果你要为上面的数组使用一个常量(使用EXCEPTIONS
),请注意,你不能在定义中定义它,而且如果你在其他类中定义它,你必须用它的名字空间来引用它。 事实上,它不一定是一个常数。
摔跤运营商
splat操作符*
“解包”一个数组在其位置,以便
rescue *EXCEPTIONS
的意思是一样的
rescue FooException, BarException
你也可以在数组中使用它
[BazException, *EXCEPTIONS, BangExcepion]
这是一样的
[BazException, FooException, BarException, BangExcepion]
或者在争论的位置
method(BazException, *EXCEPTIONS, BangExcepion)
意思是
method(BazException, FooException, BarException, BangExcepion)
[]
扩大到虚空:
[a, *[], b] # => [a, b]
ruby1.8和ruby1.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]
与其他types的对象,它返回自己。
[1, *2, 3] # => [1, 2, 3]
我刚刚遇到这个问题,并find了一个替代解决scheme。 在这种情况下,你的FooException
和BarException
都将是自定义的exception类,特别是如果它们都是关联的,你可以构造你的inheritance层次结构,使得它们将从同一个父类inheritance,然后只拯救父类。
例如,我有三个例外: FileNamesMissingError
, InputFileMissingError
和OutputDirectoryError
,我想用一个语句来拯救。 我做了另一个名为FileLoadError
exception类,然后设置上述三个exceptioninheritance它。 然后我只救了FileLoadError
。