Evgenii Legotckoi
26 августа 2016 г. 13:18

User Guide #25 - Ruby - Обработка исключительных ситуаций: ensure

Иногда бывает нужна очистка по завершении работы некоторого метода.  Возможно, должен быть закрыт открытый файл, буферизованные данные должны быть сброшены, и т.п., etc.  Если бы существовала только одна точка выхода из метода, мы могли бы уверенно поместить код очистки в одно место и быть уверены, что он будет выполнен; однако возврат из метода может происходить из нескольких точек, или наша очистка может быть пропущена из-за возникновения исключения.

  1. begin
  2.   file = open("/tmp/some_file", "w")
  3.   # ... write to the file ...
  4.   file.close
  5. end

В этом примере, если ошибка возникает во время записи файла, файл останется открытым. Также не хочется обращаться к подобной избыточности:

  1. begin
  2.   file = open("/tmp/some_file", "w")
  3.   # ... write to the file ...
  4.   file.close
  5. rescue
  6.   file.close
  7.   fail # raise an exception
  8. end

Это неуклюже, к тому же становится неуправляемым при усложнении кода, поскольку необходимо реагировать на каждые

  1. return
и
  1. break
.

По этой причине вводится новое ключевое слово в схему "

  1. begin...rescue...end
" --
  1. ensure
.  Блок
  1. ensure
выполняется независимо от успешности выполнения блока
  1. begin
.

  1. begin
  2.   file = open("/tmp/some_file", "w")
  3.   # ... write to the file ...
  4. rescue
  5.   # ... handle the exceptions ...
  6. ensure
  7.   file.close   # ... and this always happens.
  8. end

Возможно использование

  1. ensure
без
  1. rescue
, или наоборот, но если они использованы вместе в одном блоке
  1. begin...end
,
  1. rescue
должен предшествовать
  1. ensure
.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь