2.6 Packages

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

The following table depicts the general form of a package, which has two parts: a declaration and a body. Note that the package declaration always includes three reserved words (package, is, end), and the package body always includes four reserved words (package, body, is, end). The left-hand column of the table shows how a graphic symbol for a package may be expanded to represent its various parts, some of which are optional. For example, the declaration always contains a visible part, but the private part is optional.

Expanded Symbol

General Form of a package

Im2-6a.gif (2658 bytes)

package Package_Name is
  -- visible declarations
private  -- (optional)
  -- private declarations (optional)
end Package_Name;
--------------------------------------------
package body Package_Name is
  -- declarations
begin  -- (optional)
  -- initialization statements -- (optional)
end Package_Name;

Package Specification

Some texts refer to the first part of a package as its specification or "spec" for short. Actually, the declaration is the specification plus the final semi-colon.

Example Program with a User-defined Package

This diagram depicts the program listed below, including a package that exports two functions. Some details of the body of package Temperature_Conversions are also shown.. Note the symbols (round-cornered rectangles) used to represent the declarations of Base and Ratio, which are constant floating point values. We use this graphic symbol to represent any type or object declaration. We include the colon inside the symbol to indicate that the element declared is a variable or constant object. Without the colon the symbol depicts the declaration of a type or subtype -- or just a collection of declarations.

Im2-6b.gif (5080 bytes)

The next table provides a listing of the Temperature_Conversions package and the two exported functions, To_Fahrenheit and To_Celsius. The two functions are declared in the package declaration, making them available to clients, and they are implemented in the package body. (Both functions are nested units that were created using the two-step form of nesting discussed earlier.) Now that Test_Conversions has "withed in" the Temperature_Conversions package, the scope of the package as well as the two functions exported by it has been enlarged to include the Test_Conversions main procedure. The main procedure also includes three variable declarations.

Example package declaration (no private part)

package Temperature_Conversions is

  function To_Fahrenheit (C : Float) return Float;
  function To_Celsius   (F : Float) return Float;

end Temperature_Conversions;

Example package body
(initialization not needed)

 

 

 

package body Temperature_Conversions is

  Base   : constant Float := 32.0;
  Ratio  : constant Float :=  1.8;
  -------------------------------------------------
  function To_Fahrenheit (C : Float) return Float is
  begin
    return Base + Ratio*C;
  end To_Fahrenheit;
  -------------------------------------------------
  function To_Celsius(F : Float) return Float is
  begin
    return (F - Base)/Ratio;
  end To_Celsius;
  -------------------------------------------------
end Temperature_Conversions;

A procedure to test the temperature conversions package

 

 

 

 

 

 

 

 

 

 

 

 

--------------------------------------------------
--  This procedure sets up a loop, allowing the 
--  user to input values in 'F' or 'C' and have 
--  them converted to Celsius or Fahrenheit, 
--  respectively. When the user chooses 'Q' or 'q', 
--  the program quits. 
--------------------------------------------------
with Temperature_Conversions;
with Ad.Text_IO, Ada.Float_Text_IO;
procedure Test_Conversions is

  package Tcv renames Temperature_Conversions;
  package Tio renames Ada.Text_IO;
  package Fio renames Ada.Float_Text_IO;

  Input  : Float;
  Result : Float;
  Choice : Character;

begin

  loop

    Tio.Put_Line("Enter F, C or Q");
    Tio.Get(Choice);
    exit when (Choice = 'Q') or (Choice = 'q');

    if (Choice = 'F') or (Choice = 'f') then
      Tio.Put_Line("Enter a Fahrenheit value");
      Fio.Get(Input);
      Result := Tcv.To_Celsius(Input);
      Tio.Put("In Celsius that is ");
    elsif (Choice = 'C') or (Choice = 'c') then
      Tio.Put_Line("Enter a Celsius value");
      Fio.Get(Input);
      Result := Tcv.To_Fahrenheit(Input);
      Tio.Put("In Fahrenheit that is ");
    end if;
    
    Fio.Put(Result);
    Tio.New_Line;

  end loop;

end Test_Conversions;

Two different Get procedures appear above, one exported by Ada.Text_IO and the other exported by Ada.Float_Text_IO. Actually, Ada.Text_IO exports two versions of Get -- an example of overloading a name in the same unit -- one version gets a character and the other version gets a string. The compiler knows which version to call because the actual parameter, Choice, has been declared to be of type Character.

Here is a sample output from the above program:

     Enter F, C or Q
     c
     Enter a Celsius value
     20.0
     In Fahrenheit that is  6.80000E+01
     Enter F, C or Q
     f
     Enter a Fahrenheit value
     60.0
     In Celsius that is  1.55555E+01
     Enter F, C or Q
     q

Initialization During Elaboration

The (optional) executable part of a package plays a different role from that of a subprogram. During elaboration of the package the declarations are elaborated first, and then the executable part (if any) is used as an initialization sequence. All library packages are elaborated before the main procedure is entered.

The next page continues our discussion of packages and their uses.

Related Topics

2.2 Program Units 2.7 Importance and Uses of Packages

[ Back to top of pagePrev ] Next ]