У меня есть код, который должен спасти несколько типов исключений в ruby:
begin
a = rand
if a > 0.5
raise FooException
else
raise BarException
end
rescue FooException, BarException
puts "rescued!"
end
Я бы хотел как-то сохранить список типов исключений, которые я хочу где-то спасти, и передать эти типы в предложение rescue:
EXCEPTIONS = [FooException, BarException]
а потом:
rescue EXCEPTIONS
Возможно ли это вообще, и возможно ли это без некоторых действительно хакерских вызовов eval
? Я не надеюсь, учитывая, что я вижу, TypeError: class or module required for rescue clause
когда пытаюсь сделать это.
Ответы:
Вы можете использовать массив с оператором splat
*
.Если вы собираетесь использовать константу для массива, как указано выше (с
EXCEPTIONS
), обратите внимание, что вы не можете определить ее в определении, а также, если вы определяете ее в каком-либо другом классе, вы должны ссылаться на нее с ее пространством имен. На самом деле, оно не обязательно должно быть постоянным.Оператор Splat
Оператор splat
*
"распаковывает" массив в его позиции так, чтобыозначает то же, что и
Вы также можете использовать его в литерале массива как
который совпадает с
или в позиции аргумента
что значит
[]
расширяется до пустоты:Одно различие между ruby 1.8 и ruby 1.9 заключается в
nil
.Будьте осторожны с объектами, на которых
to_a
определено, какto_a
будет применяться в таких случаях:С другими типами объектов он возвращается сам.
источник
EXCEPTIONS
в этом случае? Хотел бы узнать немного больше.rescue InvalidRequestError, CardError => e
(см. Mikeferrier.com/2012/05/19/… )rescue *EXCEPTIONS => e
гдеEXCEPTIONS
- массив имен классов исключений.Пока ответ @sawa технически верен, я думаю, что он неправильно использует механизм обработки исключений Ruby.
Как следует из комментария Питера Эрлиха (указывая на старый пост в блоге Майка Ферриера ), Ruby уже оснащен механизмом обработчика исключений DRY:
Используя эту технику, мы можем получить доступ к объекту исключения, который обычно содержит ценную информацию.
источник
Я столкнулся с этой проблемой и нашел альтернативное решение. В случае, если ваш
FooException
иBarException
будут настраиваемыми классами исключений, и особенно если все они тематически связаны, вы можете структурировать свою иерархию наследования так, чтобы все они наследовали от одного и того же родительского класса, а затем спасали только родительский класс.Например , у меня было три исключения:
FileNamesMissingError
,InputFileMissingError
иOutputDirectoryError
что я хотел спасти с помощью одного оператора. Я вызвал еще один класс исключений,FileLoadError
а затем установил три вышеупомянутых исключения для наследования от него. Я тогда только спасалFileLoadError
.Как это:
источник