- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
122 Глава 5
реализации равно хороши. Самый лучший подход — сигнализировать об исключительной ситуации failure. Часто это происходит естественным образом, либо из-за того, что не обрабатывается исключительная ситуация, которая не имеет места для аргументов, принадлежащих допустимому подмножеству, либо из-за выхода на конец процедуры, которая должна возвращать результаты. (В этом случае компилятор языка CLU вставляет команды для сигнализации об исключительной ситуации failire.) В других случаях, возможно, стоит затратить некоторые усилия. Например, в процедуре merge (рис. 3.6) мы можем во время просмотра элементов массива сравнивать эти элементы с целью определить, упорядочены они или нет, и если нет, то мы сигнализируем об исключительной ситуации failure. Такие проверки — некоторая дополнительная работа, однако они существенно улучшают устойчивость программы.
Не все ошибки сызывают исключительные ситуации. Например, пусть в большом вводном файле имеется ошибочная запись и будет возможно продолжать обработку файла, пропустив эту запись. В этом случае целесообразно оповес_ти_гь_..иол.ьзователя (а не программу) о произошедшей^ошибке. Исключительные ситуа-ций^являются механизмом взаимодействия программ, а не программ с пользователями. Для взаимодействия с пользователями па какое-нибудь устройство вывода может быть выдано сообщение об ошибке. Заметим, что реакция на ошибку определяется в спецификации абстракции.
Однако исключительные ситуации не всегда связаны с ошибками. Для некоторых абстракций может быть более чем один тип обычного поведения процедур, и в этом случае исключительные ситуации — удобный инструмент. Они предоставляют средства для обеспечения нескольких типов поведения и дают возможность вызывающему процедуру различать между различными случаями.
Например, операция lookup над таблицей символов имеет две цели. Согласно заданному идентификатору, она определяет, обрабатывалось ли уже объявление этого идентификатора и если да, то возвращает информацию об этом идентификаторе. Заголовок для этой операции может быть следующим:
lookup =proc(s: symbol-table, id: string) returns (info) signals (noL in)
Здесь мы решили рассматривать случай, в котором объявление существует как обычный случай, но мы можем легко принять противоположное решение. При принятии решения следует учитывать, в частности, эффективность. Обычно исключительные ситуации требуют больших затрат, чем обычный возврат. (Это верно для языка CLU, хотя различие и мало.) Следовательно, случай, который предположительно будет возникать чаще, нужно рас-
Исключительные ситуации
сматривать как обычный случай. Если решение о том, какой случай будет обычным, принимается из соображений производительности, то очевидно, что с исключительной ситуацией не должно быть связано никаких понятий типа «ошибка».
Стоит поговорить о взаимосвязи модификации аргументов с завершением работы процедуры выходом на исключительную ситуацию. Секция modifies спецификации указывает, что аргумент может модифицироваться, но не говорит о том, когда это происходит. Если имеются исключительные ситуации, то обычно модификации происходят только для каких-нибудь из них. Что в точности происходит, должно быть описано в секции effects. Модификации должны быть описаны явно в каждом случае, в котором они совершаются; если не описано никаких модификаций, это означает, что они не совершаются вообще. Например, рассмотрим процедуру
addel == proc (s: olist [t], x: t) sinals (dupl) modifies s
effects Если x уже принадлежит s, сигнализировать об исключ. ситуации dupl, иначе включить х в s,
Так как для случая, когда процедура addel сигнализирует об исключительной ситуации dupl, не описано никаких модификаций, s модифицируется только при обычном возврате из процедуры addel,
Исключительная ситуация failure является неявной исключительной ситуацией каждой процедуры, однако она не упоминается ни в каких спецификациях. И это вполне оправданно. Спецификация описывает поведение процедуры при ее работе и для случая, когда аргументы удовлетворяют предложению requires. Исключительная ситуация failure возникает тогда, когда в работе процедуры происходит сбой и она больше не отвечает своей спецификации или когда заданы неверные аргументы. .
Обычно исключительная ситуация failure не может быть обработана программой. Эта ситуация означает либо ошибку в математическом обеспечении, либо сбой в аппаратной части. Очень устойчивая программа с анализом всевозможных ситуаций может быть способна заблокировать ошибочную часть и продолжать работать с остальным. В этом случае полезно внести ошибку в протокол, чтобы ее можно было исправить впоследствии. Менее устойчивая программа просто завершит свою работу и внесет ошибку в протокол. (Если программа выполняется в режиме отладки, пользователь у консоли может быть оповещен немедленно.)
Исключительные ситуации, о возникновении которых сигнализируют операции типов данных, связаны со специфическими операциями. Однако имена исключительных ситуаций относятся к типу в целом: либо к статусу объектов типа (например, список
