Параллельно с блоком try..except в языке существует и
try. .finally. Он соответствует случаю, когда необходимо возвратить выделенные программе ресурсы даже в случае аварийной ситуации. Синтаксис блока
try..finally таков:
try
<Оператор>
<Оператор>
...
finally
<Оператор>
...
end;
Смысл этой конструкции можно описать одним предложением: операторы, стоящие после
finally, выполняются всегда.
Следующие за try операторы исполняются в обычном порядке. Если за это время не возникло никаких ИС, далее следуют те операторы, которые стоят после
finally. В случае, если между
try и finally произошла ИС, управление немедленно передается на операторы после
finally, которые называются кодом очистки.
Допустим, вы поместили после try операторы, которые должны выделить вам ресурсы системы (дескрипторы блоков памяти, файлов, контекстов устройств и т. п.). Тогда операторы, освобождающие их, следует поместить после
finally, и ресурсы будут освобождены в любом случае. Блок
try...finally, как можно догадаться, еще называется блоком защиты ресурсов.
Важно обратить внимание на такой факт: данная конструкция ничего не делает с самим объектом — исключительной ситуацией. Задача
try...finally — только прореагировать на факт нештатного поведения программы и проделать определенные действия. Сама же ИС продолжает "путешествие" и вопрос ее обработки остается на повестке дня.
Блоки защиты ресурсов и обработчики ИС, как и другие блоки, могут быть вложенными. В этом простейшем примере каждый вид ресурсов системы защищается в отдельном блоке:
try
AllocatelstResource;
try
Allocate2ndResource;
SolveProblem;
finally
Free2ndResource;
end;
finally
FreelstResource;
end;
Можно также вкладывать обработчики друг в друга, предусмотрев в каждом специфическую реакцию на ту или иную ошибку:
var i,j,k : Integer;
begin
i := Round(Random);
j := 1 - i;
try
k := 1 div i; try
k := 1 div j;
except
On EDivByZero do
ShowMessage('Вариант 1: j=0');
end;
except
On EDivByZero do
ShowMessage('Вариант 2: i=0');
end;
end;
Но все же идеально правильный случай — это сочетание блоков двух типов. В один из них помещается общее (освобождение ресурсов в
finally), в другой — особенное (конкретная реакция внутри
except).
Знаете ли Вы, что абстракция через спецификацию - это прием программирования, позволяющий абстрагироваться от процесса вычислений описанных в теле процедуры, до уровня знания того, что данная процедура делает. Это достигается путем задания спецификации, описывающей эффект ее работы, после чего смысл обращения к данной процедуре становится ясным через анализ этой спецификации, а не самого тела процедуры. Мы пользуемся абстракцией через спецификацию всякий раз, когда связываем с процедурой некий комментарий, достаточно информативный для того, чтобы иметь возможность работать без анализа тела процедуры. Абстракция через спецификацию позволяет абстрагироваться от процесса вычислений описанных в теле процедуры, до уровня знания того, что данная процедура делает. Это достигается путем задания спецификации, описывающей эффект ее работы, после чего смысл обращения к данной процедуре становится ясным через анализ этой спецификации, а не самого тела процедуры. Мы пользуемся абстракцией через спецификацию всякий раз, когда связываем с процедурой некий комментарий, достаточно информативный для того, чтобы иметь возможность работать без анализа тела процедуры.