El cuerpo de un
paquete∞,
subprograma∞ o
tarea∞ puede ser "extraído" de la unidad o subunidad de biblioteca que lo engloba y compilarse por separado en lo que viene a denominarse subunidad. En la unidad que lo engloba, el cuerpo "extraído" se sustituye por un "resguardo" del cuerpo. Cualquier unidad de compilación puede tener subunidades.
En un ejemplo anterior, se construía un paquete de una pila de números enteros con dos procedimientos Poner y Quitar, que interesa compilar por separado, luego se escribiría:
package∞ body∞ Pila_Enteros
is∞ -- Cuerpo.
Max :
constant∞ := 100;
Pila: array(1..Max)
of∞ Integer;
Cima: Integer
range∞ 0..Max;
procedure∞ Poner (Elem: Integer)
is∞ separate∞;
-- Se compila aparte.
function∞ Quitar
return∞ Integer
is∞ separate∞;
-- Se compila aparte.
begin∞
Cima := 0;
-- Inicialización.
end∞ Pila_Enteros;
A los subprogramas que se van a compilar aparte (Poner y Quitar) se les denomina subunidades. Su cuerpo deberá implementarse en otro fichero de esta forma:
separate∞ (Pila_enteros)
-- Indica la unidad de la que se extrajo.
procedure∞ Poner (Elem: Integer)
is∞
begin∞
Cima := Cima + 1;
Pila (Cima) := Elem;
end∞ Poner;
Y de manera análoga se procedería con Quitar.
En el caso de que R sea subunidad de Q y ésta a su vez de P, que es una unidad de biblioteca, entonces la implementación de R debe comenzar con separate (P.Q).
Una subunidad depende de la unidad de la que fue separada y, por tanto debe compilarse después de ella.
La
visibilidad∞ dentro de la subunidad es exactamente igual que si no hubiera sido separada, es decir, por ejemplo, una
cláusula with∞ en la unidad principal se aplica a todas sus subunidades.
Si se necesita de una unidad únicamente dentro de una subunidad, a fin de no complicar las
dependencias∞ de compilación, se deberá incluir la cláusula with justo antes de la declaración subunidad, es decir, delante de
separate (Pila_Enteros).