Операции ”+” и ” допускают как унарную, так и бинарную совме­щенную операцию.

Явное описание функции, которая совмещает операцию ”=”, отличное от описания переименования, допустимо только если оба параметра являют­ся параметрами одного и того же лимитируемого типа. Совмещение равен­ства должно давать результат предопределенного типа BOOLEAN; опера­ция неравенства дающая результат, дополнительный к результату операции равенства, совмещается неявно при задании операции равенства. Явное совмещение операции неравенства недопустимо.

Описание переименования, обозначение которого — операция равенства, допустимо только для переименования другой операции равенства. (Напри­мер, такое описание переименования может быть, использовано, когда ра­венство видимо по имени, но не непосредственно).

Примечание. Совмещение операций отношения не нарушает соотношений, таких как проверка принадлежности диапазону или выборы в операторе выбора.

Примеры:

function ”+” (ЛЕВЫЙ, ПРАВЫЙ: МАТРИЦА) return МАТРИЦА;

function ”+” (ЛЕВЫЙ, ПРАВЫЙ: ВЕКТОР) return ВЕКТОР;

  • - в предположении, что А, В и С типа ВЕКТОР,

  • - три следующих присваивания эквивалентны

А: = В + С;

А: = ”+” (В, С);

А: = ”+” (ЛЕВЫЙ => В, ПРАВЫЙ=> С) ;

7. ПАКЕТЫ

Пакеты — это одна из четырех форм программных модулей, из кото­рых составляются программы. Другие формы - это подпрограммы, задан­ные модули и настраиваемые модули.

Пакеты допускают спецификацию групп логически связанных понятий. Простейшие формы пакета задают совокупности общих объектов и описа­ний типов. В более общем случае пакеты могут использоваться для задания групп взаимосвязанных понятий, включающих также подпрограммы, ко­торые могут быть вызваны вне пакета, тогда как внутренняя работа остает­ся скрытой и защищенной от внешних пользователей.

  1. Структура пакета

Пакет обычно представлен двумя частями: спецификацией пакета и те­лом пакета. Спецификация имеется у каждого пакета, а тело пакета имеют не все пакеты.

описание_пакета : : = спецификация_пакета;

спецификация_пакета : : =

package идентификатор is

{ основной _эл емент_описания J

[private

•f основной _элемент_описания }]

end [простое—имя_пдкега]

тело—Пакета : : =

padcage body простое_имя_пакета is

[ раздел—описаний]

[begin

последовательность—операторов

[exception

обработчик—исключения

{обработчик—исключения?] ]

end [простое—имя—пакета] ;

Простое имя в начале тела пакета должно повторять идентификатор этого пакета. Аналогично, если простое имя помещено в конце специфика­ции или тела пакета, то оно должно повторять идентификатор этого пакета.

Если описание подпрограммы, описание пакета, описание задачи или описание настройки является элементом описания в спецификации пакета, то тело (если оно существует) программного модуля, описанного этим эле­ментом описания, само должно быть элементом описания в разделе описа­ний тела того же самого пакета.

Примечание. Для простой формы пакета, задающей совокупность объектов и ти­пов, тело не обязательно. Одной из возможностей использования последовательности операторов тела пакета является инициализация таких объектов. Для каждого описа­ния подпрограммы должно существовать соответствующее ему тело (за исключением подпрограмм, написанных на другом языке, см. разд. 13.9). Если тело программного модуля является следом тела, то для этого программного модуля требуется раздель­но компилируемый субмодуль, содержащий соответствующее тело (см. 10.2). Тело не является основным элементом описания и, таким образом, не может присутство­вать в спецификации пакета.

Описание пакета - это либо библиотечный пакет (см. 10.2), либо элемент описа­ния внутри другого программного модуля.

  1. Спецификации и описание пакетов

Первый список элементов описания в спецификации пакета называется видимым разделом пакета. Необязательный список элементов описания после зарезервированного слова 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 РАБОЧИЕ-ДНИ;

  1. Тела пакетов

В отличие от понятий, описанных в видимом разделе спецификации па­кета, понятия, описанные в теле пакета, видимы только внутри самого тела пакета. Поэтому пакет с телом пакета может быть использован для созда­ния группы взаимосвязанных подпрограмм (пакет прикладных программ в обычном смысле), в которой доступные пользователям операции явно изолированы от внутренних понятий.

При предвыполнении тела пакета сначала предвыполняется его раздел описаний, а затем выполняется его последовательность операторов (если она имеется). Необязательно присутствующие в конце тела пакета обработ­чики исключений обслуживают исключения, возбуждаемые при выполне­нии последовательности операторов тела пакета.

Примечание. Переменная, описанная в тепе пакета, видима только внутри этого тела, и, следовательно, ее значение может быть изменено только внутри этого тела па­кета. В отсутствии локальных задач, значение такой переменной сохраняется неизмен­ным между вызовами извне пакета подпрограмм, описанных в его видимом разделе. Свойства такой переменной аналогичны свойствам „собственной” переменной в язы­ке Алгол 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

  1. В: РАЦИОНАЛЬНЫЙ;

begin

  1. = X;

  2. = 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 РАЦИОНАЛЬНЫЕ_ЧИСЛА;

  1. Описания личных типов и субконстант

Описание типа в качестве личного (приватного) в видимом разделе па­кета служит для отделения характеристик, которые могут быть использова­ны непосредственно внешними программными модулями (логические свой­ства) , от других характеристик, непосредственное использование которых возможно только внутри пакета (детали определения самого типа). Описа­ния субконстант задают константы личных типов. <

описание_личного_типа : : =

type идентификатор [раздел_дискриминантов] is [limited] private;

описание_субконстанты : : =

список_идентификаторов : constant обозначение_типа;

Описание личного типа допустимо только в качестве элемента описания в видимом разделе пакета или в качестве описания параметра настройки для типа в разделе формальных параметров настройки.

Обозначение типа в описании субконстанты должно обозначать личный тип или подтип личного типа. Описание субконстанты и описание соответст

­вующего личного типа должны быть оба элементами описаний в видимом разделе одного и того же пакета. Описание субконстант с несколькими идентификаторами эквивалентно последовательности единичных описаний субконстант (см. 3.2).

Примеры описаний личного типа:

type КЛЮЧ is private;

type ИМЯ_ФАЙЛА is limited private;

Пример описания субконстанты:

НУЛЕВОЙ_КЛЮЧ: constant КЛЮЧ;

  1. Личные типы

Если описание личного типа дается в видимом разделе пакета, то соот­ветствующее описание типа с тем же самым идентификатором должно при­сутствовать в качестве элемента описания в личном разделе пакета. Соот­ветствующее описание должно быть либо полным описанием типа, либо описанием задачного типа. В оставшейся части этого раздела объяснения да­ются для полных описаний типов. Те же правила применяются к описаниям задачных типов.

Описание личного типа и соответствующее полное описание типа опре­деляют один тип. Описание личного типа вместе с видимым разделом опре­деляют операции, которые могут использовать внешние программные мо­дули (см. разд. 7.4.2 об операциях, применимых к личному типу). С другой стороны, полное описание типа определяет другие операции, непосредствен­ное использование которых возможно только внутри самого пакета.

Если описание личного типа включает раздел дискриминантов, то пол­ное описание типа должно включать раздел дискриминантов по правилам согласования (см. 6.3.1), и определением типа должно быть определение именуемого типа. И наоборот, если описание личного типа не включает раз­дел дискриминантов, то тип, описанный с помощью полного описания типа (полный тип), не должен быть неограниченным типом с дискриминантами. Полный тип не должен быть неограниченным индексируемым типом. Лими­тируемый тип (в частности, задачный тип) допускается в качестве полного типа, только если в описании личного типа присутствует зарезервированное слово limited (см. 7.4.4).

Внутри спецификации пакета, в которой описан личный тип, и до конца соответствующего полного описания типа ограничено использование имени этого личного типа или его подтипа, а также имени любого типа или подти­па с подкомпонентом данного личного типа. Использование такого имени допускается только в описании субконстанты, описании типа или подтипа, спецификации подпрограммы или опйсания входа; более того, не допуска­ется использование этого имени в определениях производного типа или в простых выражениях.

При предвыполнении описания личного типа создается личный тип. Ес­ли описание личного типа имеет раздел дискриминантов, то он также пред- выполняется. Предвыполнение полного описания типа заключается в предвьі-- полнении определения типа; если имеется раздел дискриминантов, то он не предвыполняется (так как уже предвыполнен согласованный раздел дис­криминантов в описании личного типа).

Примечание. Из перечисленных правил следует, что ни описание переменной лич­ного типа, ни создание объекта личного типа с помощью генератора недопустимо до полного описания типа- Точно так же до полного описания нельзя использовать имя личного типа в конкретизации настройки или в спецификаторе представления.

  1. Операции над личным типом

Операции над личным типом, которые неявно описаны, включают базо­вые операции: присваивание (кроме лимитируемого типа), проверку при­надлежности, квалификацию, явное преобразование и именование компо­ненты для именования любого дискриминанта.

Для личного типа Т базовые операции также включают атрибуты T'BASE (см. 3.3.3) и T'SIZE (см. 13.7.2). Для объекта А личного типа базовые опе­рации включают атрибут A'CONSTRAINED, если личный тип содержит дис­криминант (см. 3.7.4), и во всех случаях - атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).

Наконец, в операции, неявно описанные описанием личного типа, вклю­чаются предопределенные отношения равенства и неравенства (кроме лич­ных типов, в описании которых присутствует зарезервированное слово li­mited) .

Рассмотренные выше операции вместе с подпрограммами, которые имеют параметр или результат личного типа и которые описаны в видимом разделе пакета, являются единственными операциями над личным типом, используемыми вне пакета.

Внутри пакета, содержащего описание личного типа, дополнительные операции вводятся неявно полным описанием типа. При этом переопределе­ние этих операций допустимо внутри той же самой зоны описаний, в том числе и между описанием личного типа и соответствующим полным описа­нием. Явно описанная подпрограмма скрывает неявно описанную опера­цию, которая имеет тот же самый профиль типа параметров и результата (это возможно только, если неявно описанной операцией является произ­водная подпрограмма или предопределенная операция).