[Перевод] Перезапуск блока кода, который стал причиной исключения
Не так давно я обнаружил одну интересную фичу в Руби. Мне показалась, что она может быть весьма полезной в определенных ситуациях. Тем не менее, я пришел к выводу, что этот трюк не так уж частно используется в коде, так как за многие годы программирования наткнулся я на него только сейчас. Идея в том, что мы можем дать еще один шанс коду, который привел к исключению (exception) и запустить его повторно. Давайте посмотрим, насколько легко это делается в руби.Мы оборачиваем определенный код в блок begin и, когда нам нужно будет запустить этот блок еще раз, просто пишем ключевое слово retry. Это может быть использовано в случае с подключением к внешним сервисам или API, которые могут работать нестабильно и иногда выдавать timeout или другие ошибки.Итак, давайте рассмотрим один простенький пример применения этому. Мы напишем метод, который будет имитировать соединение и с вероятностью примерно в 30 процентов будет выдавать исключение. Чтобы это сделать, внутри мы будем генерировать случайное число и если этим числом окажется единица — выдавать исключение. def connect tries = 0 max_tries = 3 begin raise if rand (3) == 1 rescue tries += 1 if tries == max_tries raise «We have tried #{tries} times but it still fails» else retry end end end Здесь у нас есть переменная tries, в которой мы подсчитываем сколько раз мы уже попытались запустить указанный блок. Это необходимо для того чтобы не допустить бесконечный цикл. Переменная max_tries указывает максимальное число попыток, после которого мы должны перестать пытаться запустить код и все таки выдать ошибку. Как видите, вся магия происходит в rescue блоке, когда мы вызываем retry.