В чем разница между `raise 'foo "и `raise Exception.new(" foo ")`?

В чем разница - техническая, философская, концептуальная или иная - между

raise "foo"

и

raise Exception.new("foo")

?

Ответ 1

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

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

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

begin
rescue
end

Чтобы поймать Exception, вам нужно будет сделать это:

begin
rescue Exception
end

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

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

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

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

Ответ 2

Из официальной документации:

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

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

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller