Операции ”+” и ” допускают как унарную, так и бинарную совмещенную операцию.
Явное описание функции, которая совмещает операцию ”=”, отличное от описания переименования, допустимо только если оба параметра являются параметрами одного и того же лимитируемого типа. Совмещение равенства должно давать результат предопределенного типа BOOLEAN; операция неравенства дающая результат, дополнительный к результату операции равенства, совмещается неявно при задании операции равенства. Явное совмещение операции неравенства недопустимо.
Описание переименования, обозначение которого — операция равенства, допустимо только для переименования другой операции равенства. (Например, такое описание переименования может быть, использовано, когда равенство видимо по имени, но не непосредственно).
Примечание. Совмещение операций отношения не нарушает соотношений, таких как проверка принадлежности диапазону или выборы в операторе выбора.
Примеры:
function ”+” (ЛЕВЫЙ, ПРАВЫЙ: МАТРИЦА) return МАТРИЦА;
function ”+” (ЛЕВЫЙ, ПРАВЫЙ: ВЕКТОР) return ВЕКТОР;
- в предположении, что А, В и С типа ВЕКТОР,
- три следующих присваивания эквивалентны
А: = В + С;
А: = ”+” (В, С);
А: = ”+” (ЛЕВЫЙ => В, ПРАВЫЙ=> С) ;
7. ПАКЕТЫ
Пакеты — это одна из четырех форм программных модулей, из которых составляются программы. Другие формы - это подпрограммы, заданные модули и настраиваемые модули.
Пакеты допускают спецификацию групп логически связанных понятий. Простейшие формы пакета задают совокупности общих объектов и описаний типов. В более общем случае пакеты могут использоваться для задания групп взаимосвязанных понятий, включающих также подпрограммы, которые могут быть вызваны вне пакета, тогда как внутренняя работа остается скрытой и защищенной от внешних пользователей.
Структура пакета
Пакет обычно представлен двумя частями: спецификацией пакета и телом пакета. Спецификация имеется у каждого пакета, а тело пакета имеют не все пакеты.
описание_пакета : : = спецификация_пакета;
спецификация_пакета : : =
package идентификатор is
{ основной _эл емент_описания J
[private
•f основной _элемент_описания }]
end [простое—имя_пдкега]
тело—Пакета : : =
padcage body простое_имя_пакета is
[ раздел—описаний]
[begin
последовательность—операторов
[exception
обработчик—исключения
{обработчик—исключения?] ]
end [простое—имя—пакета] ;
Простое имя в начале тела пакета должно повторять идентификатор этого пакета. Аналогично, если простое имя помещено в конце спецификации или тела пакета, то оно должно повторять идентификатор этого пакета.
Если описание подпрограммы, описание пакета, описание задачи или описание настройки является элементом описания в спецификации пакета, то тело (если оно существует) программного модуля, описанного этим элементом описания, само должно быть элементом описания в разделе описаний тела того же самого пакета.
Примечание. Для простой формы пакета, задающей совокупность объектов и типов, тело не обязательно. Одной из возможностей использования последовательности операторов тела пакета является инициализация таких объектов. Для каждого описания подпрограммы должно существовать соответствующее ему тело (за исключением подпрограмм, написанных на другом языке, см. разд. 13.9). Если тело программного модуля является следом тела, то для этого программного модуля требуется раздельно компилируемый субмодуль, содержащий соответствующее тело (см. 10.2). Тело не является основным элементом описания и, таким образом, не может присутствовать в спецификации пакета.
Описание пакета - это либо библиотечный пакет (см. 10.2), либо элемент описания внутри другого программного модуля.
Спецификации и описание пакетов
Первый список элементов описания в спецификации пакета называется видимым разделом пакета. Необязательный список элементов описания после зарезервированного слова private называется лмчньш разделом пакета.
Понятие, описанное в личном разделе пакета, не видимо вне этого пакета (имя, обозначающее такое понятие, доступно только в пакете). В противоположность этому расширенные имена, обозначающие описанные в видимом разделе понятия, могут быть использованы даже вне этого пакета; прямую видимость этих понятий можно получить также с помощью спецификатора использования (см. 4.1.3 и 8.4).
Предвыполнение описания пакета состоит в предвыполнении его основных элементов описания в порядке их следования.
Примечание. Видимый раздел пакета содержит всю информацию, доступную для другого программного модуля. Пакет, состоящий только из спецификации пакета (т. е. без тела пакета), может быть использован для представления группы общих констант или переменных, или общей совокупности объектов и типов, как показано ниже в примерах.
Пример пакета, описывающего группу общих переменных:
package ГРАФИЧЕСКИЕ_ДАННЫЕ is
ПЕРО_В:BOOLEAN;
КОЭФФИЦИЕНТ_ПЕРЕСЧЕТА,
Х_СМЕЩЕНИЕ, У.СМЕЩЕНИЕ,
Х_МИН, У_МИН, Х_МАКС, У_МАКС: ВЕЩЕСТВ; - - см. 3.5.7
Х-ЗНАЧЕНИЕ: array (1. .500) of ВЕЩЕСТВ;
У_ЗНАЧЕНИЕ: array (1. .500) of ВЕЩЕСТВ;
end ГРАФИЧЕСКИЕ-ДАННЫЕ;
Пример пакета, описывающего общую совокупность объектов и типов:
package РАБОЧИЕ_ДНИ is
type ДЕНЬ is (ИНД, ВТР, СРД, ЧТВ, ПТН, СБТ, ВСК);
type РАБОЧИЕ-ЧАСЫ is delta 0.25 range 0.0. .24.0;
type ТАБЕЛЬ-ВРЕМЕЙИ is array (ДЕНЬ) of
РАБОЧИЕ-ЧАСЫ;
ЧАСЫ-РАБОТЫ: ТАБЕЛЬ_ВРЕМЕНИ;
ОБЫЧНЫЕ-ЧАСЫ: constant ТАБЕЛЬ_ВРЕМЕНИ : =
(ПНД. .ЧТВ => 8.25, ПТН => 7.0, СБТ | ВСК => 0.0) ;
end РАБОЧИЕ-ДНИ;
Тела пакетов
В отличие от понятий, описанных в видимом разделе спецификации пакета, понятия, описанные в теле пакета, видимы только внутри самого тела пакета. Поэтому пакет с телом пакета может быть использован для создания группы взаимосвязанных подпрограмм (пакет прикладных программ в обычном смысле), в которой доступные пользователям операции явно изолированы от внутренних понятий.
При предвыполнении тела пакета сначала предвыполняется его раздел описаний, а затем выполняется его последовательность операторов (если она имеется). Необязательно присутствующие в конце тела пакета обработчики исключений обслуживают исключения, возбуждаемые при выполнении последовательности операторов тела пакета.
Примечание. Переменная, описанная в тепе пакета, видима только внутри этого тела, и, следовательно, ее значение может быть изменено только внутри этого тела пакета. В отсутствии локальных задач, значение такой переменной сохраняется неизменным между вызовами извне пакета подпрограмм, описанных в его видимом разделе. Свойства такой переменной аналогичны свойствам „собственной” переменной в языке Алгол 60.
Предвыполнение тела подпрограммы, описанной в видимом разделе пакета, осуществляется при предвыполнении тела пакета. Следовательно, при вызове такой подпрограммы извне программного модуля возбуждается исключение PROGRAM_ERROR, если вызов производится до предвыполнения тела пакета (см. 3.9).
Пример пакета:
package РАЦИОНАЛЬНЫЕ_ЧИСЛА is
type РАЦИОНАЛЬНЫЙ is
record
ЧИСЛИТЕЛЬ: INTEGER;
ЗНАМЕНАТЕЛЬ: POSITIVE;end record;
function РАВНО (X, Y: РАЦИОНАЛЬНЫЙ) return BOOLEAN;
function (X, Y: INTEGER) return РАЦИОНАЛЬНЫЙ;
- - для образования рационального числа
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ;
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ;
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ;
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ; end;
package body РАЦИОНАЛЬНЫЕ_ЧИСЛА is
procedure ОЫЦИЙ_ЗНАМЕНАТЕЛЬ (X, Y: in out РАЦИОНАЛЬНЫЙ) is begin
- - приведение X и Y к общему знаменателю:
end;
function РАВНО (X, Y: РАЦИОНАЛЬНЫЙ) return BOOLEAN is
В: РАЦИОНАЛЬНЫЙ;
begin
= X;
= Y;
ОЫЦИЙ_ЗНАМЕНАТЕЛЬ (A, B);
return А. ЧИСЛИТЕЛЬ = В.ЧИСЛИТЕЛЬ;
end РАВНО;
function ”/” (X, Y: INTEGER) return РАЦИОНАЛЬНЫЙ is begin
if Y > 0 then
return (ЧИСЛИТЕЛЬ => X, ЗНАМЕНАТЕЛЬ => Y);
else
return (ЧИСЛИТЕЛЬ => -X, ЗНАМЕНАТЕЛЬ => -Y); end if;
end
function ”+” (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ is . . .end
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ is. . .end
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ is. . .end
function (X, Y: РАЦИОНАЛЬНЫЙ) return РАЦИОНАЛЬНЫЙ is. . .end
end РАЦИОНАЛЬНЫЕ_ЧИСЛА;
Описания личных типов и субконстант
Описание типа в качестве личного (приватного) в видимом разделе пакета служит для отделения характеристик, которые могут быть использованы непосредственно внешними программными модулями (логические свойства) , от других характеристик, непосредственное использование которых возможно только внутри пакета (детали определения самого типа). Описания субконстант задают константы личных типов. <
описание_личного_типа : : =
type идентификатор [раздел_дискриминантов] is [limited] private;
описание_субконстанты : : =
список_идентификаторов : constant обозначение_типа;
Описание личного типа допустимо только в качестве элемента описания в видимом разделе пакета или в качестве описания параметра настройки для типа в разделе формальных параметров настройки.
Обозначение типа в описании субконстанты должно обозначать личный тип или подтип личного типа. Описание субконстанты и описание соответст
вующего личного типа должны быть оба элементами описаний в видимом разделе одного и того же пакета. Описание субконстант с несколькими идентификаторами эквивалентно последовательности единичных описаний субконстант (см. 3.2).
Примеры описаний личного типа:
type КЛЮЧ is private;
type ИМЯ_ФАЙЛА is limited private;
Пример описания субконстанты:
НУЛЕВОЙ_КЛЮЧ: constant КЛЮЧ;
Личные типы
Если описание личного типа дается в видимом разделе пакета, то соответствующее описание типа с тем же самым идентификатором должно присутствовать в качестве элемента описания в личном разделе пакета. Соответствующее описание должно быть либо полным описанием типа, либо описанием задачного типа. В оставшейся части этого раздела объяснения даются для полных описаний типов. Те же правила применяются к описаниям задачных типов.
Описание личного типа и соответствующее полное описание типа определяют один тип. Описание личного типа вместе с видимым разделом определяют операции, которые могут использовать внешние программные модули (см. разд. 7.4.2 об операциях, применимых к личному типу). С другой стороны, полное описание типа определяет другие операции, непосредственное использование которых возможно только внутри самого пакета.
Если описание личного типа включает раздел дискриминантов, то полное описание типа должно включать раздел дискриминантов по правилам согласования (см. 6.3.1), и определением типа должно быть определение именуемого типа. И наоборот, если описание личного типа не включает раздел дискриминантов, то тип, описанный с помощью полного описания типа (полный тип), не должен быть неограниченным типом с дискриминантами. Полный тип не должен быть неограниченным индексируемым типом. Лимитируемый тип (в частности, задачный тип) допускается в качестве полного типа, только если в описании личного типа присутствует зарезервированное слово limited (см. 7.4.4).
Внутри спецификации пакета, в которой описан личный тип, и до конца соответствующего полного описания типа ограничено использование имени этого личного типа или его подтипа, а также имени любого типа или подтипа с подкомпонентом данного личного типа. Использование такого имени допускается только в описании субконстанты, описании типа или подтипа, спецификации подпрограммы или опйсания входа; более того, не допускается использование этого имени в определениях производного типа или в простых выражениях.
При предвыполнении описания личного типа создается личный тип. Если описание личного типа имеет раздел дискриминантов, то он также пред- выполняется. Предвыполнение полного описания типа заключается в предвьі-- полнении определения типа; если имеется раздел дискриминантов, то он не предвыполняется (так как уже предвыполнен согласованный раздел дискриминантов в описании личного типа).
Примечание. Из перечисленных правил следует, что ни описание переменной личного типа, ни создание объекта личного типа с помощью генератора недопустимо до полного описания типа- Точно так же до полного описания нельзя использовать имя личного типа в конкретизации настройки или в спецификаторе представления.
Операции над личным типом
Операции над личным типом, которые неявно описаны, включают базовые операции: присваивание (кроме лимитируемого типа), проверку принадлежности, квалификацию, явное преобразование и именование компоненты для именования любого дискриминанта.
Для личного типа Т базовые операции также включают атрибуты T'BASE (см. 3.3.3) и T'SIZE (см. 13.7.2). Для объекта А личного типа базовые операции включают атрибут A'CONSTRAINED, если личный тип содержит дискриминант (см. 3.7.4), и во всех случаях - атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).
Наконец, в операции, неявно описанные описанием личного типа, включаются предопределенные отношения равенства и неравенства (кроме личных типов, в описании которых присутствует зарезервированное слово limited) .
Рассмотренные выше операции вместе с подпрограммами, которые имеют параметр или результат личного типа и которые описаны в видимом разделе пакета, являются единственными операциями над личным типом, используемыми вне пакета.
Внутри пакета, содержащего описание личного типа, дополнительные операции вводятся неявно полным описанием типа. При этом переопределение этих операций допустимо внутри той же самой зоны описаний, в том числе и между описанием личного типа и соответствующим полным описанием. Явно описанная подпрограмма скрывает неявно описанную операцию, которая имеет тот же самый профиль типа параметров и результата (это возможно только, если неявно описанной операцией является производная подпрограмма или предопределенная операция).