Яка різниця - технічна, філософська, концептуальна чи інше - між ними
raise "foo"
і
raise Exception.new("foo")
?
Яка різниця - технічна, філософська, концептуальна чи інше - між ними
raise "foo"
і
raise Exception.new("foo")
?
Відповіді:
Технічно перший піднімає RuntimeError із встановленим повідомленням "foo", а другий викликає виняток із повідомленням, встановленим на "foo".
Практично існує значна різниця між тим, коли ви хочете використовувати перше, і коли ви хочете використовувати друге.
Простіше кажучи, ви, мабуть, хочете RuntimeErrorне Exception. Рятувальний блок без аргументу застане RuntimeErrors, але НЕ вловлює Exceptions. Тож якщо ви піднімете Exceptionсвій код, цей код не зачепить його:
begin
rescue
end
Для того, щоб зловити Exceptionвас, вам доведеться зробити це:
begin
rescue Exception
end
Це означає, що в деякому сенсі Exceptionпомилка "гірше", ніж a RuntimeError, тому що вам доведеться зробити більше роботи, щоб відновити її.
Отже, чого ви хочете, залежить від того, як ваш проект виконує обробку помилок. Наприклад, у наших демонах головний цикл містить порожній рятувальний рятувальний пристрій, який буде вловлювати RuntimeErrors, повідомляти про них, а потім продовжувати. Але за однієї чи двох обставин ми хочемо, щоб демон справді помер насправді від помилки, і в такому випадку ми піднімаємо ангіну Exception, яка йде прямо через наш «звичайний код обробки помилок» і виходить.
І знову: якщо ви пишете код бібліотеки, ви, мабуть, хочете а RuntimeError, а не Exception, оскільки користувачі вашої бібліотеки будуть здивовані, якщо вони виявлять помилки, які порожній rescueблок не може наздогнати, і знадобиться їм хвилина, щоб зрозуміти, чому.
Нарешті, я повинен сказати, що RuntimeErrorце підклас StandardErrorкласу, і власне правило полягає в тому, що, хоча ви можете raise будь-який тип об'єктів, пустий rescueза замовчуванням буде тільки ловити все, що успадковується StandardError. Все інше повинно бути конкретним.
StandardError. Це не повинно бути складнішим, ніж декілька рядків class MissingArgumentsError < StandardError; end.
raise
raise( string )
raise( exception [, string [, array ] ] )
Без аргументів, збільшує виняток у $!або піднімає, RuntimeErrorякщо $!є нульовим. За допомогою одного Stringаргументу він піднімає a RuntimeErrorз рядком як повідомлення. В іншому випадку першим параметром має бути назва Exceptionкласу (або об'єкта, який повертає Exceptionвиняток при надсиланні). Необов'язковий другий параметр встановлює повідомлення, пов'язане з винятком, а третій параметр є масивом інформації про зворотний виклик. Винятки становлять рятувальний пункт begin...endблоків.
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
RuntimeError < StandardError < Exception[2] отже, цей другий блок коду охопить і виняток, і RuntimeError [3] цікаво / дивно, що "голі" підйоми та порятунки трапляються працювати саме з цим винятком [4], можливо, головним правилом є підвищення RuntimeError до клієнтського коду, але підняття та врятування власних спеціальних винятків всередині власного коду?