115

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ですか? TypeError: class or module required for rescue clause上記を試みたときに私が見ていることを考えると、私は希望を持っていません。

4

3 に答える 3

221

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]

ruby 1.8 と ruby​​ 1.9 の違いの 1 つは、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]
于 2011-04-25T20:19:26.200 に答える