Иногда бывает нужна очистка по завершении работы некоторого метода. Возможно, должен быть закрыт открытый файл, буферизованные данные должны быть сброшены, и т.п., etc. Если бы существовала только одна точка выхода из метода, мы могли бы уверенно поместить код очистки в одно место и быть уверены, что он будет выполнен; однако возврат из метода может происходить из нескольких точек, или наша очистка может быть пропущена из-за возникновения исключения.
- begin
- file = open("/tmp/some_file", "w")
- # ... write to the file ...
- file.close
- end
В этом примере, если ошибка возникает во время записи файла, файл останется открытым. Также не хочется обращаться к подобной избыточности:
- begin
- file = open("/tmp/some_file", "w")
- # ... write to the file ...
- file.close
- rescue
- file.close
- fail # raise an exception
- end
Это неуклюже, к тому же становится неуправляемым при усложнении кода, поскольку необходимо реагировать на каждые
и
- return
.
- break
По этой причине вводится новое ключевое слово в схему "
" --
- begin...rescue...end
. Блок
- ensure
выполняется независимо от успешности выполнения блока
- ensure
.
- begin
- begin
- file = open("/tmp/some_file", "w")
- # ... write to the file ...
- rescue
- # ... handle the exceptions ...
- ensure
- file.close # ... and this always happens.
- end
Возможно использование
без
- ensure
, или наоборот, но если они использованы вместе в одном блоке
- rescue
,
- begin...end
должен предшествовать
- rescue
.
- ensure