Справочник Ada 2005
7.2 Тела пакетов
В отличие от сущностей, объявленных в видимой части пакета, сущности, объявленные в теле_пакета, видимы только внутри самого тела_пакета. Вследствие этого пакет с телом_пакета можно использовать для построения группы связанных подпрограмм, в которых логические операции, доступные клиентам, чётко изолированы от внутренних сущностей.
Синтаксис
тело_пакета ::=
package body имя_определяемой_программной_единицы is
декларативная_часть
[begin
обрабатываемая_последовательность_операторов]
end [[имя_родительского_блока.]идентификатор];
package body имя_определяемой_программной_единицы is
декларативная_часть
[begin
обрабатываемая_последовательность_операторов]
end [[имя_родительского_блока.]идентификатор];
Если идентификатор или имя_родительского_блока.<идентификатор> появляется в конце тела_пакета, то эта последовательность лексем должна повторять имя_определяемой_программной_единицы.
Правила легальности
Тело пакета должно быть завершением предыдущей декларации_пакета или декларации_обобщённого_пакета. Декларация пакета в библиотеке или декларация обобщённого пакета в библиотеке не должны иметь тело, если это не требуется; pragma Elaborate_Body может использоваться для того, чтобы потребовать, чтобы декларация единицы библиотеки имела тело (см. 10.2.1), если это не требуется в ином случае.
Статическая семантика
В любом теле_пакета без операторов существует неявный пустой_оператор. Для любой декларации_пакета без явного завершения существует неявный тело_пакета, содержащий один пустой_оператор. Для неинстанцированного, небиблиотечного пакета это тело находится в конце декларативной части внутреннего включающего программного блока или блока; если таких пакетов несколько, порядок неявных тел_пакетов не определён. (Для инстанции неявное тело_пакета находится в месте инстанцирования (см. 12.3). Для библиотечного пакета место частично определяется зависимостями обработки (см. раздел 10).)
Динамическая семантика
Для обработки тела необобщённого пакета сначала обрабатывается его декларативная_часть, а затем выполняется его обрабатываемая_последовательность_операторов.
ПРИМЕЧАНИЯ
3 Переменная, объявленная в теле пакета, видима только внутри этого тела и, следовательно, её значение может быть изменено только внутри тела_пакета. При отсутствии локальных задач значение такой переменной не изменяется между вызовами, произведёнными извне пакета, в подпрограммы, объявленные в видимой части. Свойства такой переменной аналогичны свойствам «статической» переменной языка С.
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;