1. ホーム
  2. ruby

[解決済み] ruby の rescue 節に複数のエラークラスを DRY に渡す方法

2022-09-24 21:01:18

質問

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 が表示されていることを考えると、期待できません。

どのように解決するのですか?

配列にスプラット演算子 * .

EXCEPTIONS = [FooException, BarException]

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

上記のように配列に定数を使用する場合、( EXCEPTIONS で)、定義の中では定義できないこと、また、他のクラスで定義する場合は、その名前空間で参照する必要があることに注意してください。実際には、定数である必要はありません。


スプラットオペレーター

スプラット演算子 * というように、配列をその位置で展開します。

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の違いのひとつは 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]