Вопросы по обработке исключений в Ruby - PullRequest
3 голосов
/ 30 апреля 2009

Я изучал книгу по программированию на Ruby, и у меня возникли проблемы с пониманием следующих концепций:

  1. Авторы говорят о «переходных исключениях», которые могут возникнуть в коде, а затем предлагают создать собственный объект исключения для их обработки. Я не думаю, что полностью понимаю, что такое временная ошибка и когда уместно создать собственный объект Exception. Он говорит об этом в главе 6 , когда говорит об определении исключений:

Например, некоторые типы сетевых ошибок могут быть временными. Глава 6.Страница 97. Добавление информации в исключения.

  1. Мне также трудно осваивать использование Catch and Throw в ruby. Когда это лучше, чем поднять и спасти?

1 Ответ

11 голосов
/ 30 апреля 2009

Можете ли вы дать нам ссылку на страницу в строке «временные исключения»?

В любом случае вы можете создать новое исключение в любое время, и обычно это полезно, чтобы вы могли передавать больше информации о сбое. Это особенно хорошо, когда у вас есть исключение нижнего уровня и вы хотите сделать его более значимым для пользователя.

Throw / Catch в Ruby на самом деле является своего рода нелокальным переходом, например setjmp / longjmp в C, но ведет себя лучше. Вы будете использовать его в любое время, когда хотите перенести выполнение долгими путями.

Очевидно, по той же причине, по которой вы не хотите много использовать goto, вы не хотите этого делать. Основная причина, по которой вы могли бы использовать его, заключается в том, что программа должна продолжать работать, поэтому, если вы обнаружите определенные виды ошибок, вы можете сбросить всю часть выполняемой вами работы и вернуться к началу. *


Ладно, этого нет на странице 97 ни одного из изданий кирки, которые у меня есть, но я понимаю, что это значит. ... о, вот она, стр. 157 в третьем издании.

Прежде всего, в отношении «переходного процесса» существуют некоторые проблемы с сетью, которые могут возникнуть, а затем решить их самостоятельно, например, когда BOFH отключает сетевой кабель и подключает его обратно. Возможно, вы захотите дать ему несколько секунд, чтобы успокоиться и попробовать еще раз, прежде чем запаниковать. как бы ты это сделал?

В этом случае у них вы определяете новый тип исключения. Это делается только с наследованием:

class RetryException < RuntimeError
  # so this is a kind of RuntimeError which is a kind of Exception
  attr: ok_to_retry
  def initialize(ok_to_retry)
     @ok_to_retry
  end
end

поэтому, если что-то пойдет не так, вы можете поднять эти новые повторяющиеся исключения

raise RetryException.new(true), "transient read error"

, который теперь отправляет что-то вроде RuntimeError в стек, но теперь к нему прикреплена дополнительная информация, т. Е. Флаг, который говорит «да, это можно повторить».

Теперь, в Ruby есть действительно изящная вещь: она имеет встроенную возможность повторять некоторые вещи. Итак, где-то вверх по стеку, у вас есть этот код:

begin
   # do something that raises this exception
   do_something()
rescue RetryException => detail 
   # if the exception is one of these retryable ones, 
   # catch it here, but it in detail
   if detail.ok_to_retry  
      retry
   end
   # this means exactly the same as 'retry if detail.ok_to_retry`
   # from the book, btw

   # if it STILL doesn't work, send the exception on
   raise # just re-raises the last exception
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...