Инструкции
ОО-нотация, разработанная в этой книге, императивна: вычисления специфицируются через команды (commands), также называемые инструкциями (instructions). (Мы избегаем обычно применимого термина оператор (предложение) (statement), поскольку в слове есть оттенок выражения, описывающего факты, а хотелось подчеркнуть императивный характер команды.)
Для имеющих опыт работы с современными языками инструкции выглядят как хорошие знакомые. Исключение составляют некоторые специальные свойства циклов, облегчающие их верификацию. Вот список инструкций: Вызов процедуры, Присваивание, Условие, Множественный выбор, Цикл, Проверка, Отладка, Повторное выполнение, Попытка присваивания.
Вызов процедуры
При вызове указывается имя подпрограммы, возможно, с фактическими аргументами. В инструкции вызова подпрограмма должна быть процедурой. Вызов функции является выражением. Хотя сейчас нас интересуют инструкции, следующие правила применимы в обоих случаях.
Вызов может быть квалифицированным или неквалифицированным. Для неквалифицированного вызова подпрограммы из включающего класса в качестве цели используется текущий экземпляр класса. Этот вызов имеет вид:
r (без аргументов), или
r (x, y, …) (с аргументами)
Квалифицированный вызов явно называет свою цель, заданную некоторым выражением. Если a — выражение некоторого типа, C — базовый класс этого типа, а — q одна из программ C, то квалифицированный вызов имеет форму a.q. Опять же, за q может следовать список фактических аргументов; a может быть неквалифицированным вызовом функции с аргументами, как в p (m).q (n), где p(m) — это цель. В качестве цели можно также использовать более сложное выражение при условии заключения его в скобки, как в (vector1 + vector2).count.
Также разрешаются квалифицированные вызовы с многоточием в форме: a.q1q2 …qn, где a, так же, как и qi, может включать список фактических аргументов.
Экспорт управляет применением квалифицированных вызовов. Напомним, что компонент f, объявленный в классе B, доступен в классе A ( экспортирован классу ), если предложение feature, объявляющее f, начинается с feature (без дальнейшего уточнения) или feature {X, Y,… }, где один из элементов списка {X, Y,…} является A или предком A. Имеет место:
Правило Квалифицированного Вызова
Квалифицированный вызов вида b.q1. q2…. qn, появляющийся в классе C корректен, только если он удовлетворяет следующим условиям:
- Компонент, стоящий после первой точки, q1, должен быть доступен в классе C.
- В вызове с многоточием, каждый компонент после второй точки, то есть каждое qi для i > 1, должен быть доступен в классе C.
Чтобы понять причину существования второго правила, отметим, что a.q.r.s — краткая запись для
которая верна только, если q, r и s доступны классу C, в котором появляется этот фрагмент. Не имеет значения, доступно ли r базовому классу типа q, и доступно ли s базовому классу типа r.
Вызовы могут иметь инфиксную или префиксную форму. Выражение a + b, записанное в инфиксной форме, может быть переписано в префиксной форме: a.plus (b). Для обеих форм действуют одинаковые правила применимости.
Присваивание (Assignment)
Инструкция присваивания записывается в виде:
где x — сущность, допускающая запись (writable), а e — выражение совместимого типа. Такая сущность может быть:
- неконстантным атрибутом включающего класса;
- локальной сущностью включающей подпрограммы. Для функции допустима сущность Result.
Сущности, не допускающие запись, включают константные атрибуты и формальные аргументы программы — которым, как мы видели, подпрограмма не может присваивать новое значение.
Создание (Creation)
Инструкция создания изучалась в предыдущих лекциях3См. «Инструкция создания» и «Процедуры создания»,
«Динамические структуры: объекты»
. Один из вариантов рассмотрен в «Полиморфное создание»,
«Введение в наследование»
.
в двух ее формах: без процедуры создания, как в create x, и с процедурой создания, как в create x.p (…). В обоих случаях x должна быть сущностью, допускающей запись.
Условная Инструкция (Conditional)
Эта инструкция задает различные формы обработки в зависимости от выполнения определенных условий. Основная форма:
if boolean_expression then instruction; instruction; ... else instruction; instruction; ... end
где каждая ветвь может иметь произвольное число инструкций (а возможно и не иметь их).
Будут выполняться инструкции первой ветви, если boolean_expression верно, а иначе — второй ветви. Можно опустить часть else, если второй список инструкций пуст, что дает:
if boolean_expression then instruction; instruction; ... end
Когда есть более двух возможных случаев, можно избежать вложения (nesting) условных команд в частях else, используя одну или более ветвей elseif, как в:
if c1 then instruction; instruction; ... elseif c2 then instruction; instruction; ... elseif c3 then instruction; instruction; ... ... else instruction; instruction; ... end
где часть else остается факультативной. Это дает возможность избежать вложения
if c1 then instruction; instruction; ... else if c2 then instruction; instruction; ... else if c3 then instruction; instruction; ... ... else instruction; instruction; ... end end end
Когда необходим множественный разбор случаев, более удобна инструкция множественного выбора inspect, обсуждаемая ниже.
ОО-метод, благодаря полиморфизму и динамическому связыванию, уменьшает необходимость явных условных инструкций и множественного выбора, поддерживая неявную форму выбора. Когда объект применяет некоторый компонент, имеющий несколько вариантов, то во время выполнения нужный вариант выбирается автоматически в соответствии с типом объекта. Этот неявный стиль выбора обычно предпочтительнее, но, конечно, инструкции явного выбора остаются необходимыми.
Множественный выбор
Инструкция множественного выбора (также известная, как инструкция Case ) производит разбор вариантов, имеющих форму: e = vi, где e — выражение, а vi — константы того же типа. Хотя условная инструкция (if e = v1 then …elseif e = v2 then…) работает, есть две причины, оправдывающие применение специальной инструкции, что является исключением из обычного правила: «если нотация дает хороший способ сделать что-то, нет необходимости вводить другой способ». Вот эти причины:
- Разбор случаев настолько распространен, что заслуживает особого синтаксиса, увеличивающего ясность, позволяя избежать бесполезного повторения » e = «.
- Компиляторы могут использовать особенно эффективную технику реализации, — таблицу переходов ( jump table ), — неприменимую к общим условным инструкциям и избегающую явных проверок.
Что касается типа анализируемых величин (тип e и vi ), то инструкции множественного выбора достаточно поддерживать только целые и булевы значения. Согласно правилу, они фактически должны объявляться либо все как INTEGER, либо как CHARACTER. Общая форма инструкции такова:
inspect e when v1 then instruction; instruction; ... when v2 then instruction; instruction; ... ... else instruction; instruction; ... end
Все значения vi должны быть различными; часть else факультативна; каждая из ветвей может иметь произвольное число инструкций или не иметь их.
Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.
Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi «. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.
Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем4Это элементарная схема. О более сложных технических приемах обработки пользовательских команд см. лекцию 3 курса «Основы объектно-ориентированного проектирования«.
:
inspect first_input_letter when 'D' then "Удалить строку" when 'I' then "Вставить строку" ... else message ("Неопознанная команда; введите H для получения справки") end
Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.
Как и условные инструкции, инструкции множественного выбора не должны использоваться для замены неявного выбора, основанного на динамическом связывании.
Циклы
Синтаксис циклов описан при обсуждении Проектирования по Контракту (
«Проектирование по контракту: построение надежного ПО»
):
from initialization_instructions invariant invariant variant variant until exit_condition loop loop_instructions end
Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция ( null instruction ); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.
Проверка
Инструкция проверки рассматривалась при обсуждении утверждений (
«Проектирование по контракту: построение надежного ПО»
). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:
check assertion -- Одно или больше предложений end
Отладка
Инструкция отладки является средством условной компиляции. Она записывается так:
debug instruction; instruction; ... end
В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.
Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.
Повторение вычислений
Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (
«Когда контракт нарушается: обработка исключений»
). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.
Проверка
Проверка
Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:
check
assertion — Одно или больше предложений
end
Читайте также
Проверка
Проверка
Установка цветов в соответствии с правилами может здорово помочь при проверке данных на этапе ввода. Например, аварийным красным будут выделяться значения, явно выходящие за рамки указанного диапазона, или подсвечиваться желтым «подозрительные» слова и цифры.
1.5. Проверка на совместимость
1.5. Проверка на совместимость
Перед установкой Windows 7 очень полезно сделать предварительную оценку того, справится ли компьютер с новой системой или нет. Кроме того, не забывайте, что подключенные и отлично работающие в данный момент внешние устройства совсем не
Проверка диска
Проверка диска
Изменение времени ожиданияПри загрузке Windows после неправильного выключения запускается проверка дисков. При этом пишется что-то вроде «Через 10 секунд начну проверять…». Чтобы уменьшить время ожидания надо в разделе HKLMSYSTEMCurrentControlSetControlSession Managerсоздать или
Проверка внедрения
Проверка внедрения
В разделе «Проверка внедрения» описываются шаги, позволяющие убедиться в том, что операции выполняются в соответствии с установленным процессом. В этот раздел обычно входят проверки и аудиты со стороны руководства и работы по обеспечению качества
7.2.5. Проверка внедрения
7.2.5. Проверка внедрения
Раздел «Проверка внедрения» обычно содержит ключевые практики, относящиеся к надзору со стороны руководителей проекта и высшего руководства, а также конкретные контрольные мероприятия, проводимые группой обеспечения качества или другими лицами
Проверка внедрения
Проверка внедрения
Проверка 1 Регулярная проверка высшим руководством выполнения операций по управлению установленными требованиями.Регулярные проверки проводятся высшим руководством для получения своевременной информации о процессе разработки ПО и его понимания
Проверка внедрения
Проверка внедрения
Проверка 1 Регулярная проверка высшим руководством выполнения работ по планированию разработки.Регулярные проверки проводятся высшим руководством для получения своевременной информации о производственном процессе и его понимания на
Проверка внедрения
Проверка внедрения
Проверка 1 Регулярная проверка высшим руководством выполнения работ по отслеживанию хода проекта и контролю над ним.Регулярные проверки проводятся высшим руководством для получения своевременной информации о производственном процессе и его
Проверка внедрения
Проверка внедрения
Проверка 1 Регулярная проверка высшим руководством выполнения работ по управлению субподрядом.Регулярные проверки проводятся высшим руководством для получения своевременной информации о процессе разработки ПО и его понимания на соответствующем
Проверка внедрения
Проверка внедрения
Проверка 1 Регулярная проверка высшим руководством работ по обеспечению качества.Регулярные проверки проводятся высшим руководством для получения своевременной информации о ходе процесса разработки ПО и его понимания на соответствующем уровне
Проверка внедрения
Проверка внедрения
Проверка 1. Регулярная проверка высшим руководством работ по управлению конфигурацией.Регулярные проверки проводятся высшим руководством для получения своевременной информации о процессе разработки ПО и его понимания на соответствующем уровне
Проверка внедрения
Проверка внедрения
Проверка 1. Регулярная проверка высшим руководством выполнения мероприятий по разработке и усовершенствованию производственного процесса.Регулярные проверки проводятся высшим руководством для получения своевременной информации о
Проверка внедрения
Проверка внедрения
Проверка 1. Проведение группой обеспечения качества проверок и/или аудитов работ и промежуточных продуктов, касающихся разработки и сопровождения СППО и связанных с ним основных средств, а также выполнение отчетов по их результатам.См. группу
Проверка
Проверка
Так ли уж правильны наши рассуждения? Давайте проверим нашу функцию на учебной программе:/* проверка функции getint( )*/#define STOP — 1#define NONUM 1#define YESNUM 0main( ){int num, status;printf(» Программа прекращает считывание чисел, если встречает EOF.
» );while((status = getint(&num)) != STOP)if(status = =
Проверка
Проверка
Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:checkassertion — Одно или больше
Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.
Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi«. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.
Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем13.4):
inspect
first_input_letter
when 'D' then
"Удалить строку"
when 'I' then
"Вставить строку"
...
else
message ("Неопознанная команда; введите H для получения справки")
end
Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.
Как и условные инструкции, инструкции множественного выбора не должны использоваться для замены неявного выбора, основанного на динамическом связывании.
Циклы
Синтаксис циклов описан при обсуждении Проектирования по Контракту (лекция 11):
from
initialization_instructions
invariant
invariant
variant
variant
until
exit_condition
loop
loop_instructions
end
Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция (null instruction); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.
Проверка
Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:
check
assertion -- Одно или больше предложений
end
Отладка
Инструкция отладки является средством условной компиляции. Она записывается так:
debug instruction; instruction; ... end
В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.
Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.
Повторение вычислений
Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.
Выражения
Выражение задает вычисление, вырабатывающее значение, — объект или ссылку на объект. Выражениями являются:
[x]. неименованные (манифестные) константы;
[x]. сущности (атрибуты, локальные сущности, формальные аргументы, Result);
[x]. вызовы функций;
[x]. выражения с операторами (технически — это специальный случай вызова функций);
[x]. Current.
Манифестные константы
Неименованная или манифестная константа задается значением, синтаксис которого позволяет определить и тип этого значения, например, целое 0. Этим она отличается от символьной константы, чье имя не зависит от значения.
Булевых констант две, — True и False. Целые константы имеют обычную форму, например:
453 -678 +66623
В записи вещественных (real) констант присутствует десятичная точка. Целая, либо дробная часть может отсутствовать. Может присутствовать знак и экспонента, например:
52.5 -54.44 +45.01 .983 -897. 999.e12
Символьные константы состоят из одного символа в одинарных кавычках, например, ‘A’. Для цепочек из нескольких символов используется библиотечный класс STRING, описанный ниже.
Вызовы функций
Вызовы функций имеют такой же синтаксис, как и вызовы процедур. Они могут быть квалифицированные и неквалифицированные: в первом случае используется нотация с многоточием. При соответствующих объявлениях класса и функций, они, например, таковы:
b.f
b.g(x, y, ...)
b.h(u, v).i.j(x, y, ...)
Правило квалифицированного вызова, приведенное для процедур, применимо также к вызовам функций.
Текущий объект
Зарезервированное слово Current означает текущий экземпляр класса и может использоваться в выражении. Само Current — тоже выражение, а не сущность, допускающая запись. Значит присваивание Current, например, Current := some_value будет синтаксически неверным.
анализ символа, введенного пользователеманализ символа, введенного пользователем 13.4
Нестрогие булевы операторы
Операторы and then и or else (названия заимствованы из языка Ada), а также implies не коммутативны и называются нестрогими (non-strict) булевыми операторами. Их семантика следующая:
Нестрогие булевы операторы
[x]. a and then b ложно, если a ложно, иначе имеет значение b.
[x]. a or else b истинно, если a истинно, иначе имеет значение b.
[x]. a implies b имеет то же значение, что и: (not a) or else b.
Первые два определения, как может показаться, дают ту же семантику, что и and и or. Но разница выявляется, когда b не определено. В этом случае выражения, использующие стандартные булевы операторы, математически не определены, но данные выше определения дают результат: если a ложно, то a and then b ложно независимо от b; а если a истинно, то a and then b истинно независимо от b. Аналогично, a implies b истинно, если a ложно, даже если b не определено.
Итак, нестрогие операторы могут давать результат, когда стандартные не дают его. Типичный пример:
(i /= 0) and then (j // i = k)
которое, согласно определению, ложно, если i равно 0. Если бы в выражении использовался and, а не and then, то из-за неопределенности второго операнда при i равном 0 статус выражения неясен. Эта неопределенность скажется во время выполнения:
1 Если компилятор создает код, вычисляющий оба операнда, то во время выполнения произойдет деление на ноль, и возникнет исключительная ситуация.
2 Если же генерируется код, вычисляющий второй операнд только тогда, когда первый истинен, то при i равном 0 возвратится значение ложь.
Для гарантии интерпретации (2), используйте and then. Аналогично,
(i = 0) or else (j // i /= k)
истинно, если i равно 0, а вариант or может дать ошибку во время выполнения.
Можно недоумевать, почему необходимы два новых оператора — не проще и не надежнее ли просто поддерживать стандарт операторов and и or и принимать, что они означают and then и or else? Это не изменило бы значение булева выражения, когда оба оператора определены, но расширило бы круг случаев, где выражения могут получить непротиворечивое значение. Именно так некоторые языки программирования, в частности, ALGOL, W и C, интерпретируют булевы операторы. Однако есть теоретические и практические причины сохранять два набора различных операторов.
[x]. С точки зрения теории, стандартные математические булевы операторы коммутативны: a and b всегда имеет значение такое же, как b and a, в то время как a and then b может быть определенным, когда b and then a не определено. Когда порядок операндов не имеет значения, предпочтительно использовать коммутативный оператор.
[x]. С точки зрения практики, некоторые оптимизации компилятора становятся невозможными, если требуется, чтобы компилятор вычислял операнды в заданном выражением порядке, как в случае с некоммутативными операторами. Поэтому лучше использовать стандартные операторы, если известно, что оба операнда определены.
Отметим, что можно смоделировать нестрогие операторы посредством условных команд на языке, не включающем такие операторы. Например, вместо
b := ((i /= 0) and then (j // i = k))
можно написать
if i = 0 then b := false else b := (j // i = k) end
Нестрогая форма, конечно, проще. Это особенно ясно, когда она используется как условие выхода из цикла:
from
i := a.lower
invariant
— Для всех элементов из интервала [a.lower .. i — 1], (a @ i) /= x
variant
a.upper — i
until
i > a.upper or else (a @ i = x)
loop
i := i + 1
end;
Result := (i <= a.upper)
Цель — сделать Result верным, если и только если значение x находится в массиве a. Использование or здесь будет неверным. В этом случае всегда могут вычисляться два операнда, так что при истинности первого операнда (i > a.upper) произойдет попытка доступа к несуществующему элементу массива a @(aupper+1), что приведет к ошибке во время выполнения (нарушение предусловия при включенной проверке утверждений).
Решение без нестрогих операторов будет неэлегантным.
Другой пример — утверждение, например, инварианта класса, выражающее, что первое значение списка l целых неотрицательно, при условии, что список непустой:
l.empty or else l.first >= 0
При использовании or инвариант был бы некорректен. Здесь нет способа написать условие без нестрогих операторов (кроме написания специальной функции и вызова ее в утверждении). Базовые библиотеки алгоритмов и структур данных содержат много таких случаев.
Оператор implies, описывающий включения, также нестрогий. Форма implies менее привычна, но часто более ясна, например, последний пример выглядит лучше в записи:
(not l.empty) implies (l.first >= 0)
[x]. Компиляторы могут использовать особенно эффективную технику реализации, — таблицу переходов (jump table), — неприменимую к общим условным инструкциям и избегающую явных проверок.
Что касается типа анализируемых величин (тип e и vi), то инструкции множественного выбора достаточно поддерживать только целые и булевы значения. Согласно правилу, они фактически должны объявляться либо все как INTEGER, либо как CHARACTER. Общая форма инструкции такова:
inspect
e
when v1 then
instruction; instruction; …
when v2 then
instruction; instruction; …
…
else
instruction; instruction; …
end
Все значения vi должны быть различными; часть else факультативна; каждая из ветвей может иметь произвольное число инструкций или не иметь их.
Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.
Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi«. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.
Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем13.4):
inspect
first_input_letter
when ‘D’ then
«Удалить строку»
when ‘I’ then
«Вставить строку»
…
else
message («Неопознанная команда; введите H для получения справки»)
end
Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.
Как и условные инструкции, инструкции множественного выбора не должны использоваться для замены неявного выбора, основанного на динамическом связывании.
Циклы
Синтаксис циклов описан при обсуждении Проектирования по Контракту (лекция 11):
from
initialization_instructions
invariant
invariant
variant
variant
until
exit_condition
loop
loop_instructions
end
Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция (null instruction); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.
Проверка
Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:
check
assertion — Одно или больше предложений
end
Отладка
Инструкция отладки является средством условной компиляции. Она записывается так:
debug instruction; instruction; … end
В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.
Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.
Повторение вычислений
Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.
Выражения
Выражение задает вычисление, вырабатывающее значение, — объект или ссылку на объект. Выражениями являются:
[x]. неименованные (манифестные) константы;
[x]. сущности (атрибуты, локальные сущности, формальные аргументы, Result);
[x]. вызовы функций;
[x]. выражения с операторами (технически — это специальный случай вызова функций);
[x]. Current.
Манифестные константы
Неименованная или манифестная константа задается значением, синтаксис которого позволяет определить и тип этого значения, например, целое 0. Этим она отличается от символьной константы, чье имя не зависит от значения.
Булевых констант две, — True и False. Целые константы имеют обычную форму, например:
453 -678 +66623
В записи вещественных (real) констант присутствует десятичная точка. Целая, либо дробная часть может отсутствовать. Может присутствовать знак и экспонента, например:
Читать дальше