Справочное руководство по языку Ада-83

         

Пакеты


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

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

Ссылки: задачный модуль 9, настраиваемый модуль 12, описание типа 1, подпрограмма 6, программный модуль 6.



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


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

описание-личного-типа ::= type идентификатор [раздел-дискриминантов] is [limited] private;описание-субконстанты ::= список-идентификаторов : constant обозначение-типа;

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

Обозначение типа в описании субконстанты должно обозначать личный тип или подтип личного типа. Описание субконстанты и описание соответствующего личного типа должны быть оба элементами описаний в видимом разделе одного и того же пакета. Описание субконстант с несколькими идентификаторами эквивалентно последовательности описаний субконстант с одним идентификатором, как объяснено в разд.

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

type KEY is private;

type FILENAME is limited private;

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

NULLKEY : constant KEY;

Ссылки: видимый раздел 7.2, идентификатор 2.3, константа 1, лимитируемый тип 4, личный тип 1, обозначение типа 2, описание 3.1, описание параметра настройки 12.1, пакет 7, подтип 3.3, программный модуль 6, раздел дискриминанта 1, раздел формальных параметров настройки 12.1, список идентификаторов 3.2, тип 3.3, формальный тип настройки 12.1, элемент описания

1. ЛИЧНЫЕ ТИПЫ

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

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

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

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

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

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

Ссылки: видимый раздел 7.2, выражение 4.4, генератор 4.8, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, индексируемый тип 3.6, конкретизация настройки 12.3, лимитируемый тип 4, личный раздел 7.2, личный тип 7.4, неограниченный индексируемый тип 3.6, неполное описание типа 1, операция 3.3, описание входа 9.5, описание личного типа 7.4, описание подтипа 2, описание субконстанты 3, описание типа 1, определение именуемого типа 3.7, определение типа 1, пакет 7, переменная 1, подкомпонента 3.3, подтип 3.3, полное описание типа 1, Предвыполнение 3.9, производный тип 3.4, раздел дискриминанта 1, согласованный 1, спецификатор представления 13.1, спецификация пакета 7.1, спецификация подпрограммы 6.1, тип 3.3, элемент описания

2. ОПЕРАЦИИ НАД ЛИЧНЫМ ТИПОМ

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

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

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

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

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

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

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

Те же правила относятся к неявно описанным для ссылочного типа операциям, чье обозначение типа есть личный тип или тип, описанный посредством неполного описания типа.

Для каждого личного типа или полтипа Т определен следующий атрибут:

T'CONSTRAINED Вырабатывает значение FALSE, если Т обозначает неограниченный неформальный личный тип с дискриминантами, не являющийся формальным параметром настройки; вырабатывает также значения FALSE, если Т обозначает личный тип, являющийся формальным параметром настройки, а соответствующий подтип фактического параметра является либо неограниченным типом с дискриминантом, либо неограниченным индексируемым типом; в остальных случаях вырабатывает значение TRUE. Значение атрибута имеет предопределенный тип BOOLEAN.

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

Последствия такой фактической реализации сказываются тем не менее везде. Например, производится некоторая инициализация компонент по умолчанию; атрибут SIZE вырабатывает раз'мер полного типа; правила зависимости задач распространяются также на компоненты — объекты задачного типа.

Пример:

package KEY_MANAGER is type KEY is private; NULL_KEY : constant KEY; procedure GET_KEY(K : out KEY); function "<" (X, Y : KEY) return BOOLEAN: private type KEY is new NATURAL: NULLKEY : constant KEY := 0; end;package body KEY_MANAGER is LAST_KEY : KEY := 0; procedure GET_KEY(K : out KEY) is begin LAST_KEY := LAST_KEY + 1; К := LAST_KEY; end GET_KEY; function "<" (X. Y : KEY) return BOOLEAN is begin return INTEGER(X) < INTEGER(Y); end "<"; end KEY_MANAGER;

Примечание к примеру: Операциями, применимыми к объектам типа KEY вне пакета KEY MANAGER являются: присваивание, сравнение на равенство и неравенство, процедура GET_KEY и операция "<"; сюда не включаются другие операции отношения, например >=или арифметические операции.

Явно описанная операция " <" скрывает предопределенную операцию < , неявно опи_ санную полным описанием типа. В теле функции необходимо явное преобразование Х и Y к типу INTEGER для явного вызова операции "<" над этим типом. С другой стороны результат функции мог бы быть записан в виде not(X > = Y), так как операция " > = не переопре-

Значение переменной LAST_KEY, описанной в теле пакета, не меняется между вызовами процедуры GET_KEY (см. также примечание к разд. 7.3).

Ссылки- атрибут 4, базовая операция 3, видимый раздел 7.2, дискриминант 3.3, зависимость задач 9.4, именованная компонента 3, квалификация 4.7, компонента 3.3, контроль принадлежности 4.5, личный тип 7.4, неполное описание типа 1, непосредственная областьдействия 8.2, неявное описание 3.1, область описания 8.1, основная операция 3, операция 3.3, операция отношения 4.5, описание 3.1, описание личного типа 7.4, пакет 7, параметр подпрограммы 6.2, подпрограмма 6, полное описание типа 1, полный тип 1, предопределенная операция 4.5, предопределенная функция 8.6, преобразование 4.6, присваивание 5.2, программный модуль 6, производная подпрограмма 3.4, производный тип 3.4, равенство 2, размерность 3.6, скрытие 8.3, составной тип

3. СУБКОНСТАНТЫ

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

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

Предвыполнение описания субконстанты не дает другого эффекта.

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

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

Ссыпки: видимый раздел 7.2, выражение по умолчанию для дискриминанта 1, идентификатор 2.3, именуемая компонента 3.7, личный раздел 7.2, обозначение типа 2, описание константы 1, описание объекта 1, описание субконстанты 7.4, пакет 7, Предвыполнение не дает другого эффекта 3.1, согласованный 1, спецификация пакета 7.1, субконстанта 7.4, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3, элемент описания

4. ЛИМИТИРУЕМЫЕ ТИПЫ

Лимитируемый тип — это тип, для которого неявным описанием не вводится ни присваивание, ни сравнение на равенство и неравенство.

Описание личного типа с зарезервированным словом limited описывает лимитируемый тип. Задачный тип является лимитируемым типом. Производный тип от лимитируемого типа сам является лимитируемым типом. Наконец, составной тип является лимитируемым, если тип одной из его компонент является лимитируемым.

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

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

Из правил для лимитируемых типов вытекает следующее:

• Если тип объекта является лимитируемым, то в описании этого объекта явная инициализация недопустима.

• Если тип именуемой компоненты является лимитируемым, то выражение по умолчанию в описании компоненты недопустимо.

• Если тип объекта, указанного ссылочным типом, является лимитируемым, то в генераторе явная инициализация недопустима.

• Формальный параметр настройки вида in не должен быть лимитируемого типа. Примечание. Описанные выше правила не исключают выражение по умолчанию для формального параметра лимитируемого типа; они не исключают также субконстанту лимитируемого типа, если полный тип не является лимитируемым. Для лимитируемого типа допускается явное описание операции равенства (см. 6.7).

Для лимитируемого составного типа не разрешаются агрегаты (см. 2 и 4). Для лимитируемого индексируемого типа не разрешается катенация (см. 2).

Пример:

package I_O_PACKAGE is type FILE_NAME is limited private; procedure OPEN (F in out FILE_NAME); procedure CLOSE (F in out FILE_NAME); procedure READ (F in FILE_NAME; ITEM : out INTEGER); procedure WRITE (F in FILE_NAME; ITEM : in INTEGER); private type FILE_NAME is record INTERNAL_NAME : INTEGER := 0; end record; end I_0_PACKAGE;package body I_0_PACKAGE is LIMIT : constant := 200; type FILE_DESCRIPTOR is record ... end record; DIRECTORY : array (1 .. LIMIT) of P1LE_DESCRIPTOR; ... procedure OPEN (F in out FILE_NAME) is ... end; procedure CLOSE (F in out FILEJMAME) Is ... end; procedure READ (F in FILE_NAME; ITEM : out INTEGER) is ... end: procedure WRITE (F in FILEJMAME; ITEM : in INTEGER) Is ... end; begin ... end I_O_PACKAGE;

Примечание к примеру. В приведенном примере для внешних подпрограмм, использующих !_ О-PACKAGE, имя файла можно получить в результате вызова процедуры OPEN, а затем использовать его в вызовах процедур READ и WRITE. Следовательно, вне пакета имя файла, полученное после вызова процедуры OPEN, выполняет функцию пароля; его внутренние свойства (например, содержать числовое значение) неизвестны, и никакие другие операции (такие как сложение или сравнение внутренних имен) над этим именем не могут выполняться.

Этот пример характерен для тех случаев, когда желателен полный контроль над операциями. Такие пакеты служат двум целям: они препятствуют пользователю в использовании внутренней структуры типа, а также реализуют понятие упрятывания (скрытия) типа данных, для которых определены только заданные в спецификации пакета операции.

Ссылки: агрегат 4.3, вид 1, выражение по умолчанию для дискриминанта 3.7, генератор 4.8, задачный тип 9.1, 9.2, именуемая компонента 3.7, именуемый тип 3.7, личный тип 7.4, начальное значение 1, неявное описание 3.1, обозначает 3.8, объект 3.2, операция 3.3, операция катенации 4.5, операция отношения 4.5, описание компоненты 3.7, описание личного типа пакет 7, подкомпонента 3.3, подпрограмма 6, полное описание типа 1, полный тип 1, предопределенная операция 4.5, присваивание 5.2, производный тип 3.4, равенство 2, составной тип 3.3, спецификация дискриминанта 1, субконстанта 3, тип 3.3, тип компоненты 3.3, формальный параметр 6.1, формальный параметр настройки 12.1,



Пример пакета обработки текстов


Этот пример иллюстрирует простой пакет обработки текстов. Пользователи имеют доступ только к видимому разделу; реализация от них скрыта в личном разделе и теле пакета (тело не показано).

С точки зрения пользователя, TEXT является строкой переменной длины. Каждый текстовый объект имеет максимальную длину, которая должна задаваться при описании этого объекта, и текущую длину, которая равна длине в диапазоне от нуля до максимального. Максимальная возможная длина текстового объекта является константой, определяемой реализацией.

Сначала в пакете определяются необходимые типы, затем функции, возвращающие некоторые характеристики объектов типа, затем функции преобразования текстов и предопределенных типов CHARACTER и STRING и, наконец, некоторые стандартные операции над переменными строками. Большинство операций над строками, символами, а также над типом TEXT совмещены для минимизации числа явных преобразований, которые должен написать пользователь.

package TEXT_HANDLER is MAXIMUM : constant := SOME_VALUE; -— это значение определено реализацией subtype INDEX it INTEGER range 0 .. MAXIMUM; type TEXT(MAXIMUM_LENGTH : INDEX) is limited private; function LENGTH (T TEXT) return INDEX; function VALUE (T TEXT) return STRING; function EMPTY (T TEXT) return BOOLEAN; function TO_TEXT (S STRING; MAX : INDEX) return TEXT; -- максимальная длина МАХ function TO_TEXT (С CHARACTER; MAX : INDEX) return TEXT; function TO_TEXT (S STRING) return TEXT; - - максимальная длина S'LENGTH function TO_TEXT (C CHARACTER) return TEXT; function "&" (LEFT : TEXT; RIGHT TEXT) return TEXT; function "&" (LEFT : TEXT; RIGHT STRING) return TEXT; function "&" (LEFT : STRING; RIGHT TEXT) return TEXT; function "&" (LEFT : TEXT; RIGHT CHARACTER) return TEXT; function "&" (LEFT : CHARACTER; RIGHT TEXT) return TEXT; function "=" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN; function "<" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN; function "<=" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN; function ">" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN; function ">=" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN; procedure SET (OBJECT ; in out TEXT; VALUE : In TEXT); procedure SET (OBJECT : In out TEXT; VALUE : In STRING); procedure SET (OBJECT : In out TEXT; VALUE : in CHARACTER); procedure APPEND (TAIL : In TEXT; TO In out TEXT); procedure APPEND (TAIL : in STRING; TO In out TEXT); procedure APPEND (TAIL : In CHARACTER; TO in out TEXT); procedure AMEND (OBJECT in out TEXT; BY In TEXT; POSITION : In INDEX); procedure AMEND (OBJECT in out TEXT; BY In STRING; POSITION : In INDEX); procedure AMEND (OBJECT In out TEXT; BY In CHARACTER; POSITION : In INDEX); -— заменяет часть объекта с заданной позиции на данный -— текст, строку или символ function LOCATE (FRAGMENT : TEXT; WITHIN : TEXT) return INDEX; function LOCATE (FRAGMENT : STRING; WITHIN : TEXT) return INDEX; function LOCATE (FRAGMENT : CHARACTER; WITHIN : TEXT) return INDEX; —- возвращают значение О, если фрагмент не размещаетсяprivate type TEXT(MAXIMUM_LENGTH : INDEX) is record POS : INDEX := 0; VALUE : STRING(1 .. MAXIMUM_LENGTH); end record;end TEXT-HANDLER;

Пример использования пакета обработки текста:

Программа открывает файл вывода, имя которого дается строкой NAME. Эта строка имеет вид

[УСТРОЙСТВО :] [ИМЯ ТИПА [.РАСШИРЕНИЕ]]

Для устройства, имени файла и расширения существуют стандартные значения по умолчанию. Названное пользователем имя передается через параметр функции EXPAND_FILE_NAME, ее результатом является расширенная версия с необходимыми добавлениями по умолчанию.

function EXPAND_FILE_NAME (NAME : STRING) return STRING is use TEXT_HANDLER; DEFAULT_DEVICE : constant STRING = "SY:"; DEFAULT_FILE_NAME : constant STRING = "RESULTS"; DEFAULT_EXTENSION : constant STRING = ".DAT"; MAXIMUM_FILE_NAME_LENGTH : constant INDEX := SOME_APPROPRIATE_VALUE: FILE_NAME : TEXT(MAXIMUM_FILE_NAME_LENGTH);begin SET(FILE_NAME, NAME); if EMPTY(FILE_NAME) then SET(FILE_NAME, DEFAULT_FILE_NAME); end if; if LOCATEC:', FILE_NAME) = 0 then SET(FILE_NAME, DEFAULT_DEVICE & FILE_NAME); end if; if LOCATE('.', FILE_NAME) = 0 then APPEND(DEFAULT_EXTENSION, TO => FILE_NAME); end if; return VALUE(FILE_NAME);end EXPAND_FILE_NAME;

Пример пакета работы с таблицами


Следующий пример иллюстрирует использование пакетов для организации простого взаимодействия пользователя с довольно сложными процедурами.

Необходимо создать пакет для работы с таблицами по внесению и извлечению их элементов. Элементы включаются в таблицу по мере их поступления. Каждый поступивший элемент имеет порядковый номер. Элементы выбираются в соответствии с их порядковыми номерами, причем первым выбирается элемент с наименьшим порядковым номером.

С точки зрения пользователя, пакет чрезвычайно прост. Существует тип с именем ITEM — тип элемента таблицы, есть процедура INSERT для включения элементов в таблицу и процедура RETRIEVE для извлечения элемента с наименьшим порядковым номером. Если таблица пуста, то возвращается специальный элемент NULL-ITEM, а если таблица заполнена, то при выяпяй nnniiftnvnki INRFRT по.чЛужляйтся искпючание TABLE _FULL-

Ниже приведена схема такого пакета. Пользователю известна только спецификация пакета.

package TABLE_MANAGER is type ITEM is record ORDER_NUM : INTEGER; ITEM_CODE : INTEGER; QUANTITY : INTEGER; ITEM-TYPE : CHARACTER; end record; NULL-ITEM : constant ITEM := (ORDER_NUM | ITEM_CODE | QUANTITY => 0, ITEM_TYPE => ' '); procedure INSERT (NEWJTEM : in ITEM); procedure RETRIEVE (FIRSTJTEM : out ITEM); TABLE_FULL : exception; -— это исключение возбуждается в процедуре end; -— INSERT, если таблица заполнена

Детали реализации таких пакетов могут быть достаточно сложными; в данном случае используются двусвязные списки внутренних элементов. Локальная вспомогательная процедура EXCHANGE используется для перемещения внутренних элементов из списка занятых в список свободных. Начальные связи таблицы устанавливаются в разделе инициализации. Нет необходимости показывать пользователям тело пакета.

package body TABLE_MANAGER is SIZE : constant := 2000; subtype INDEX is INTEGER range 0 .. SIZE; type INTERNAL-ITEM is record CONTENT : ITEM; SUCC : INDEX; PRED : INDEX; end record; TABLE : array (INDEX) of INTERNAL-ITEM; FIRST_BUSY_ITEM : INDEX := 0; FIRST_FREE_ITEM : INDEX := 1; function FREE_LIST_EMPTY return BOOLEAN is ... end; function BUSY_LIST_EMPTY return BOOLEAN is ... end; procedure EXCHANGE (FROM : in INDEX; TO : in INDEX) is ... end; procedure INSERT (NEWJTEM : in ITEM) is begin if FREE_LIST_EMPTY then raise TABLE_FULL; end if; -— остальная часть кода подпрограммы INSERT end INSERT; procedure RETRIEVE (FIRSTJTEM : out ITEM) is ... end;begin -— инициализация связей таблицы end TABLE_MANAGER;

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


Первый список элементов описания в спецификации пакета называется видимым разделом пакета. Необязательный список элементов описания после зарезервированного слова private называется личным разделом пакета.

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

Предвыполнение описания пакета состоит в предвыполнении его основных элементов описания в порядке их следования.

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

Пример пакета, описывающего группу общих переменных:

package PLOTTING_DATA is PEN_UP : BOOLEAN; CONVERSION_FACTOR, X_OFFSET, Y_OFFSET, X_MIN, Y_MIN, X_MAX, Y_MAX: REAL; -— CM. 7 X_VALUE : array (1 .. 500) of REAL; Y_VALUE : array (1 .. 500) of REAL; end PLOTTING-DATA;

Пример пакета, описывающего общую совокупность объектов и типов:

package WORK_DATA is type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN); type HOURS_SPENT is delta 0.25 range 0.0 .. 24.0; type TIME_TABLE is array (DAY) of HOURS_SPENT; WORK_HOURS : TIME_TABLE; NORMAL_HOURS : contant TIME_TABLE := (MON .. THU => 8.25, FRI ==> 7.0, SAT | SUN => 0.0>; end WORK_DATA;

Ссылки: идентификатор пакета 7.1, имя 4.1, константа 1, область действия 8.2, описание объекта 1, описание пакета 7.1, описание типа 1, описание числа 2, основной элемент описания 3.9, пакет 7, переменная 1, Предвыполнение 3.9, простое имя 4.1, прямая видимость 8.3, расширенное имя 3, спецификатор использования 8.4, спецификация пакета 7.1, элемент описания



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


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

описание-пакета ::= спецификация-пакета;спецификация -пакета ::= package идентификатор is {основной-элемент-описания} [private {основной-элемент-описания)] end [простое-имя-пакета]тело-пакета ::= package body простое-имя-пакета is [раздел - описаний] [begin последовательность-операторов [exception обработчик-исключения {обработчик-исключения}]] end [простое-имя-пакета];

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

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

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

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

Ссылки: библиотечный модуль 10.1, идентификатор 2.3, настраиваемое тело 12.2, обработчик исключения 11.2, объект 3.2, описание задачи 9.1, описание настройки 12.1, описание подпрограммы 6.1, основной элемент описания 3.9, последовательность операторов 5.1, программный модуль 6, простое имя 4.1, раздел описаний 3.8, след тела 10.2, соответствующее тело 3.9, субмодуль 10.2, тело задачи 9.1, тело пакета 7.3, тело подпрограммы 6.3, тип 3.3, элемент описания



Тела пакетов


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

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

Примечание. Переменная, описанная в теле пакета, видима только внутри этого тела, и, следовательно, ее значение может быть изменено только внутри этого тела пакета. В отсутствие локальных задач значение такой переменной сохраняется неизменным между вызовами извне пакета подпрограмм, описанных в его видимом разделе. Свойства такой переменной аналогичны свойствам «собственной» переменной в языке Алгол-60.

Предвыполнение тела подпрограммы, описанной в видимом разделе пакета, осуществляется при предвыполнении тела пакета. Следовательно, при вызове такой подпрограммы извне программного модуля возбуждается исключение PROGRAM-ERROR, если вызов производится до предвыполнения тела пакета (см. 3.9).

Пример пакета:

package RATIONAL-NUMBERS is type RATIONAL is record NUMERATOR : INTEGER; DENOMINATOR : POSITIVE; end record; function EQUAL (X,Y RATIONAL) return BOOLEAN; function "/" (X,Y INTEGER) return RATIONAL; —- для образования рационального числа function "+" (X,Y RATIONAL) return RATIONAL; function "-" (X,Y RATIONAL) return RATIONAL; function "*" (X,Y RATIONAL) return RATIONAL; function "/" (X,Y RATIONAL) return RATIONAL;end;package body RATIONAL-NUMBERS is procedure SAME-DENOMINATOR (X,Y : in out RATIONAL) is begin -- приведение Х и Y к общему знаменателю; end; function EQUAL(X,Y : RATIONAL) return BOOLEAN is U,V : RATIONAL; begin U := X; V := Y; SAME-DENOMINATOR (U,V); return ENUMERATOR = V.NUMERATOR; end EQUAL; function "/" (X,Y : INTEGER) return RATIONAL is begin if Y > 0 then return (NUMERATOR => X, DENOMINATOR => Y); else return (NUMERATOR => -X, DENOMINATOR => -Y); end if; end"/"; function "+" (X,Y RATIONAL) return RATIONAL is ... end "+"; function "-" (X,Y RATIONAL) return RATIONAL is ... end "-"; function "*" (X,Y RATIONAL) return RATIONAL is ... end "*"; function "/" (X,Y RATIONAL) return RATIONAL is ... end "/";end RATIONAL_NUMBERS;

Ссылки: видимый раздел 7.2, имя 4.1, исключение 11, исключение PROGRAM-ERROR 11.1, ДЮЗ обработчик исключения 11.1, описание 3.1, переменная 1, подпрограмма б, последовательность операторов 5.1, Предвыполнение 3.1, 3.9, .программный модуль 6, раздел описаний 3.9, спецификация пакета