[ Table of Contents ]
Here is an example illustrating the use of a separately compiled subunit, which is physically separate but logically nested in the body of a package. The package body code contains a body stub. The motivation for having this capability is that we can later modify (perhaps to improve performance) the "stubbed-out" unit, without having to modify and recompile the enclosing unit and other units which depend upon it.
The package depicted on the right side of this diagram defines an abstract data type with five legal operations. One of the five, Sort_Array, is "stubbed out" and is separately compiled outside of the package body. The test procedure encloses an inner procedure, Create_And_Test, which declares an actual array of the abstract type declared in the package. The outer procedure determines the size of the array before calling the inner procedure. The Temperature_Conversions package is reused (see earlier example) and is not listed here. |
Note that we could substitute different implementations of our Sort_Array procedure, without having to modify and recompile the enclosing Temperature_Array package.
Source Code Listing
------------------- Temperature_Array -------------------- -- This ADT package provides a data type that is an -- unconstrained array of floating point values and -- that has five operations. One of these, the -- Sort_Array procedure is declared as a separately -- compiled subunit. ---------------------------------------------------------- package Temperature_Array is function Get_Size return Positive; type Data_Type is array (Integer range <>) of Float; procedure Get_Values (Data : in out Data_Type); procedure Convert_To_Celsius (Data : in out Data_Type); procedure Convert_To_Fahrenheit(Data : in out Data_Type); procedure Sort_Array (Data : in out Data_Type); procedure Show_Array (Data : in Data_Type); end Temperature_Array; ---------------------------------------------------------- with Ada.Text_IO; with Ada.Integer_Text_IO; with Ada.Float_Text_IO; with Temperature_Conversions; package body Temperature_Array is package Tio renames Ada.Text_IO; package Iio renames Ada.Integer_Text_IO; package Fio renames Ada.Float_Text_IO; package TC renames Temperature_Conversions; ------------------------------------------------ function Get_Size return Positive is Size : Positive; begin Tio.Put_Line("Enter value of Size (Positive)"); Iio.Get(Size); Tio.New_Line; return Size; end Get_Size; ------------------------------------------------ procedure Get_Values(Data : in out Data_Type) is begin for I in Data'Range loop Tio.Put("Enter data value "); Fio.Get(Data(I)); end loop; Tio.New_Line; end Get_Values; -------------------------------------------------------- procedure Convert_To_Celsius(Data : in out Data_Type) is begin Tio.Put_Line("Converting to Celsius"); for I in Data'Range loop Data(I) := TC.To_Celsius(Data(I)); end loop; end Convert_To_Celsius; ---------------------------------------------------------- procedure Convert_To_Fahrenheit(Data : in out Data_Type) is begin Tio.Put_Line("Converting to Fahrenheit"); for I in Data'Range loop Data(I) := TC.To_FahrenHeit(Data(I)); end loop; end Convert_To_Fahrenheit; ---------------------------------------------------------- procedure Sort_Array(Data : in out Data_Type) is separate; -- stub ---------------------------------------------------------- procedure Show_Array(Data : in Data_Type) is begin Tio.Put_Line("Temperature Data"); for I in Data'Range loop Fio.Put(Data(I)); Tio.Put(" "); if I mod 5 = 0 then Tio.New_Line; end if; end loop; Tio.New_Line; Tio.New_Line; end Show_Array; --------------------------------- end Temperature_Array; ---------------------------------------------------------- --------------- Separate compilation unit ---------------- ---------------------- Sort_Array ------------------------ separate (Temperature_Array) procedure Sort_Array(Data : in out Data_Type) is Temporary : Float; begin Tio.Put_Line("Sorting array"); for N in reverse 1..(Data'Last - 1) loop for I in 1..N loop if Data(I) > Data(I+1) then Temporary := Data(I); Data(I) := Data(I+1); Data(I+1) := Temporary; end if; end loop; end loop; end Sort_Array; --------------------------------------------------------- ---------------- Test_Temperature_Array ----------------- -- This procedure encloses an inner procedure that does -- most of the testing work. First,the outer procedure -- determines the size of the array to be declared by -- the inner procedure. --------------------------------------------------------- with Temperature_Array; procedure Test_Temperature_Array is package TA renames Temperature_Array; Size : Positive; -------------------------------- procedure Create_And_Test is Data : TA.Data_Type (1..Size); begin TA.Get_Values(Data); TA.Show_Array(Data); TA.Sort_Array(Data); TA.Show_Array(Data); TA.Convert_To_Celsius(Data); TA.Show_Array(Data); TA.Convert_To_Fahrenheit(Data); TA.Show_Array(Data); end Create_And_Test; -------------------------------- begin Size := TA.Get_Size; Create_And_Test; end Test_Temperature_Array; --------------------------------------------------------- --------------------------------------------------------- |
Here is a sample output from the above program:
Enter value of Size (Positive) 4 Enter data value 32 Enter data value 77 Enter data value 59 Enter data value 23 Temperature Data 3.20000+01 7.70000+01 5.90000+01 2.30000+01 Converting to Celsius Temperature Data 0.00000+00 2.50000+01 1.50000+01 -5.00000+00 Sorting array Temperature Data -5.00000+00 0.00000+00 1.50000+01 2.50000+01 |
Related Topics
[ Back to top of page ]