Справочник по Ada 2012
7.2 Тела пакетов
В отличие от сущностей, объявленных во видимой части пакета, сущности, объявленные в теле_пакета, видны только внутри самого тела_пакета. Вследствие этого, пакет с телом_пакета может использоваться для построения группы связанных подпрограмм, в которых логические операции, доступные клиентам, чётко изолированы от внутренних сущностей.
Синтаксис
тело_пакета ::=
package body имя_определяемого_блока
[описание_аспекта] is
разделяющая_часть
[begin
обрабатываемая_последовательность_операторов]
end [[имя_родительского_блока.]идентификатор];
package body имя_определяемого_блока
[описание_аспекта] is
разделяющая_часть
[begin
обрабатываемая_последовательность_операторов]
end [[имя_родительского_блока.]идентификатор];
Если идентификатор или имя_родительского_блока.идентификатор появляется в конце тела_пакета, то эта последовательность лексем должна повторять имя_определяемого_блока.
Правила корректности
Тело пакета должно быть завершением предыдущего объявления_пакета или объявления_родового_пакета. Объявление пакета или объявление родового пакета в библиотеке не должно иметь тело, если это не требуется; псевдоним Elaborate_Body может использоваться для требования тела объявления_единицы_библиотеки (см. 10.2.1), если это не требуется по умолчанию.
Статическая семантика
В любом теле_пакета без операторов есть неявный пустой_оператор. Для любого объявления пакета без явного завершения существует неявное тело_пакета, содержащее единственный пустой_оператор. Для неинстанцируемого, небиблиотечного пакета это тело располагается в конце разделяющей_части самого внутреннего блока программы или блочного_оператора; если таких пакетов несколько, порядок неявных тел_пакетов не определён. (Для инстанции неявное тело_пакета происходит в месте инстанциации (см. 12.3). Для библиотечного пакета место частично определяется зависимостями от расширения (см. главу 10).)
Динамическая семантика
Для обработки неродового тела_пакета сначала обрабатывается его разделяющая_часть, а затем выполняется обрабатываемая_последовательность_операторов.
ПРИМЕЧАНИЯ
3 Переменная, объявленная в теле пакета, видна только внутри этого тела и, следовательно, её значение может быть изменено только внутри тела_пакета. При отсутствии локальных задач значение такой переменной остаётся неизменным между вызовами извне пакета подпрограммам, объявленным в видимой части. Свойства такой переменной аналогичны свойствам "статической" переменной C.
4 Обработка тела подпрограммы, явно объявленной в видимой части пакета, вызывается обработкой тела пакета. Таким образом, вызов такой подпрограммы внешним блоком программы вызывает исключение Program_Error, если вызов происходит до обработки тела_пакета (см. 3.11).
Примеры
Пример тела пакета (см. 7.1):
package body Rational_Numbers is
procedure Same_Denominator (X,Y : in out Rational) is
begin
-- сводит X и Y к общему знаменателю:
...
end Same_Denominator;
begin
-- сводит X и Y к общему знаменателю:
...
end Same_Denominator;
function "="(X,Y : Rational) return Boolean is
U : Rational := X;
V : Rational := Y;
begin
Same_Denominator (U,V);
return U.Numerator = V.Numerator;
end "=";
U : Rational := X;
V : Rational := Y;
begin
Same_Denominator (U,V);
return U.Numerator = V.Numerator;
end "=";
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 "/";
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 "/";
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;