2011-01-26 2 views

ответ

100

Технически, первый поднимает RuntimeError с сообщением, установленным в "foo", а второй вызывает исключение с сообщением, установленным в "foo".

Практически существует существенная разница между тем, когда вы хотите использовать первое и когда хотите использовать последний.

Проще говоря, вы, вероятно, хотите RuntimeError не Exception. Блок спасения без аргумента поймает RuntimeErrors, но НЕ поймает Exception s. Так что если вы поднять Exception в код, этот код не будет поймать его:

begin 
rescue 
end 

Для того, чтобы поймать Exception вам придется это сделать:

begin 
rescue Exception 
end 

Это означает, что в некотором смысле , Exception является «худшей» ошибкой, чем RuntimeError, потому что вам нужно сделать больше работы, чтобы оправиться от нее.

Так что вы хотите, зависит от того, как ваш проект справляется с ошибками. Например, у наших демонов основной цикл имеет пустое спасение, которое поймает RuntimeErrors, сообщит об этом, а затем продолжит. Но в одном или двух случаях мы хотим, чтобы демон действительно действительно умирал от ошибки, и в этом случае мы поднимаем Exception, который проходит прямо через наш «нормальный код обработки ошибок» и выходит.

И опять же, если вы пишете код библиотеки, вы, вероятно, хотите RuntimeError, не Exception, так как пользователи вашей библиотеки будут удивлены, если это вызывает ошибки, пустой rescue блок не может поймать, и он будет принимать им нужно понять, почему.

Наконец, я должен сказать, что RuntimeError является подклассом StandardError класса, а фактическое правило таково, что, хотя вы можете raiseлюбой типа объекта, заготовка rescue будет по умолчанию только поймать что-нибудь, что наследуется от StandardError ,Все остальное должно быть конкретным.

+1

очень информативный, спасибо. несколько вещей: [1] Последний абзац был самым ярким, и позволил мне обнаружить в irb то, о чем вы не упоминали: «RuntimeError

+1

[1, 2] Да. [3] не уверен ... [4] Когда я кодирую в своем самом профессиональном, я склонен создавать собственные типы ошибок, которые наследуются от «StandardError». Это не должно быть сложнее, чем несколько строк, например 'class MissingArgumentsError

+0

Очень информативно, но в каких ситуациях вы захотите выбросить исключение, а не ошибку времени выполнения, если ошибка времени выполнения предпочтительна для написания либрана? –

26

From the offical documentation:

raise 
raise(string) 
raise(exception [, string [, array ] ]) 

без аргументов, вызывает исключение в $! или поднимает RuntimeError если $! равна нулю. С одним аргументом String он поднимает RuntimeError со строкой в ​​виде сообщения. В противном случае первым параметром должно быть имя класса Exception (или объект, который возвращает Exception при отправленном исключении). Второй необязательный параметр устанавливает сообщение, связанное с исключением, а третий параметр представляет собой массив информации обратного вызова. Исключения попадают в резервную позицию блоков begin...end.

raise "Failed to create socket" 
raise ArgumentError, "No parameters", caller 
Смежные вопросы