- •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
108 Глава 5
ошибкой, более конструктивно рассматривать этот случай особо, чтобы использующему данную процедуру программисту было труднее игнорировать эту ошибку по невнимательности. Кроме того, если каждое значение возвращаемого типа есть возможный результат процедуры (как в случае с процедурой choose), то это решение не приводит к положительному результату, так как нет значения, с помощью которого можно было бы оповестить об ошибке. Предпочтительнее был бы метод, который не зависел бы от того, есть такое значение или нет.
Такой метод может быть получен через обобщение процедур. Вместо того чтобы иметь одну область определения, мы разделим область определения D на некоторое число подмножеств, объединение которых дает D:
D=DoU^U...UDn
Каждое подмножество «особо» в том смысле, что процедура ведет себя по-разному на каждом из них. Например, для операции choose мы можем разделить область определения на два подмножества:
Do = ^все непустые наборы^ Di == {пустой набор}
Если аргумент принадлежит Do, процедура choose, как и раньше, возвращает выбранное целое число. Если аргумент принадлежит Di, также осуществляется возврат из процедуры, но так, что пользователь оповещается о возникшей проблеме. Как мы уже отмечали, невозможно оповестить пользователя, используя целое число, так как любое целое число является потенциальным результатом для какого-то аргумента из Do. Следовательно, необходим другой метод оповещения.
Мы обеспечим оповещение, имея различные области изменения для каждого подмножества области определения и придав различным случаям различные имена. Произвольно дадим случаю аргумента из Do имя «обычный». Имена для других случаев могут быть выбраны тем, кто определяет процедуру. Таким образом, имеем р: do —>- обычный (ro) di -»- ИМЯ1 (ri)
Dn -^ имя„ (Rn)
где имя^, ..., имяц — имена «исключительных» ситуаций, соответствующих аргументам, принадлежащим Di,... Dn соответственно, а Но, ... Rn описывает число, порядок и типы результатов, возвращаемых в каждом случае. Имя^ ..., имяп называются исключительными ситуациями. Например, имеем
choose: Do ->• обычный (int) Di ->- empty ( )
. где Pi пусто, так как в этом случае пользователю не возвращается никакого результата.
В этой главе мы будем говорить о том, как специфицировать, реализовывать и использовать процедуры с исключительными ситуациями. Рассмотрим также некоторые связанные с этим темы.
р 5.1. Спецификации
Л Чтобы специфицировать процедуры, которые вызывают исключительные ситуации, добавим в спецификацию предложение signals:
signals % здесь приводится список имен и результатов исключительных ситуаций
Это предложение — часть заголовка. Оно следует за предложением returns. Если исключительных ситуаций не имеется, оно может быть опущено. Исключительные ситуации должны быть разделены запятыми, а их результаты (если такие имеются) должны быть заключены в скобки. Например, предложение
choose = proc (i: intset) returns (int) signals (empty)
говорит о том, что процедура choose может вызывать исключительную ситуацию empty и что в этом случае не возвращается никакого результата. Предложение же
search = proc (a: array [int], х: int) returns (ind: int) signals (not-in, duplicate (indi: int))
говорит о том, что процедура ^earch может вызывать две исключительные ситуации: not-in /(без результата) и duplicate (результат—целое число). Имя indi вводится для ссылок на этот результат в остальной части спецификации.
Как и раньше, секция effects должна определять поведение процедуры для всех фактических аргументов, отвечающих предложению requires. Так как это поведение включает в себя исключительные ситуации, секция effects должна определять, что приводит к вызову каждой исключительной ситуации и что делает процедура в каждом таком случае. Если процедура сигнализирует об исключительной ситуации для аргументов, принадлежащих D;, возможные значения аргументов, принадлежащие D,, не должны Напутствовать в предложении requires. Завершение процедуры оповещением об исключительной ситуации — это один из нормальных режимов работы этой процедуры.
