You need limited with
, which was introduced to address exactly this problem. See the Rationale for Ada 2005, section 4.2.
Animals
and Persons
are symmetric (my editor has adjusted the layout and casing; I’ve added one record component to each so the demo program, below, can print something):
limited with Animals;
package Persons is
-- One of the few things you can do with an incomplete type, which
-- is what Animals.Animal is in the limited view of Animals, is to
-- declare an access to it.
type AnimalPOINTER is access Animals.Animal;
type Person is record
Name : Character;
Animalref : AnimalPOINTER;
end record;
end Persons;
limited with Persons;
package Animals is
type PersonPOINTER is access Persons.Person;
type Animal is record
Name : Character;
Ownerref : PersonPOINTER;
end record;
end Animals;
The demo program has the full view of Animals
and Persons
. This example is pretty clumsy; you may be able to organise things better by adding subprograms to Animals
and Persons
. Note that the body of Animals
can (and must) with Persons;
if it needs to use anything in Persons
.
with Ada.Text_IO; use Ada.Text_IO;
with Animals;
with Persons;
procedure Animals_And_Persons is
A : Persons.animalPOINTER := new Animals.Animal;
P : Animals.PersonPOINTER := new Persons.Person;
begin
A.all := (Name => 'a', Ownerref => P);
P.all := (Name => 'p', Animalref => A);
Put_Line (P.Name & " owns " & P.Animalref.Name);
Put_Line (A.Name & " is owned by " & A.Ownerref.Name);
end Animals_And_Persons;
which when compiled and run gives
$ ./animals_and_persons
p owns a
a is owned by p