Previous | Table of Contents | Next |
Here the exception handler protects just the one Get. If the call succeeds, the exit statement passes control to just below the end loop. If the Get fails on an exception, the handlers recover, perhaps writing a message to the interactive user, after which control passes below the end, back around the loop for another attempt.
Completing the example, lines 81-88 loop through the transaction database and create the summary array and then lines 90-103 display the results. The statement
Money_Out.Put(Item => TodaysSummary(WhichKind).Net, Pic => Ada.Text_IO.Editing.To_Picture ($$_$$$_$$9.99CR));
displays the monetary quantity in edited form, using a parameter Pic of type Ada.Text_IO.Editing.Picture to provide the desired format. These picture strings are similar to those in COBOL and in spreadsheet programs. In this case, I have indicated a floating dollar sign, commas to separate groups of digits, and CR to indicate a negative monetary value. Thus -2065.00 displays as $2,065.00CR.
As in other systems used to program financial reports, Ada picture strings have many rules and much flexibility. Edited formats need not even be programmed statically. Because a picture is, syntactically, just a string, it need not be supplied as a literal but can be constructed on-the-fly depending on other conditions and passed to Put at the last moment.
This is the last example of the brief Ada programs designed to illustrate types and objects, the inner syntax of the language, and a number of the standard library packages. The next section shows how programs are constructed from packages.
This section illustrates the use of packages with some of my own. Before doing so, it is useful to examine a standard library package, namely the full interface of Ada.Calendar, taken verbatim from the Reference Manual because it is an especially good example of careful design of appropriate operations. Also, many Ada packagesstandard and application specificfollow the general structure of Ada.Calendar.
1 package Ada.Calendar is 2 3 type Time is private; 4 5 subtype Year_Number is Integer range 1901 .. 2099; 6 subtype Month_Number is Integer range 1 .. 12; 7 subtype Day_Number is Integer range 1 .. 31; 8 subtype Day_Duration is Duration range 0.0 .. 86_400.0; 9 10 function Clock return Time; 11 12 function Year (Date: Time) return Year_Number; 13 function Month (Date: Time) return Month_Number; 14 function Day (Date: Time) return Day_Number; 15 function Seconds(Date: Time) return Day_Duration; 16 17 procedure Split (Date : in Time; 18 Year : out Year_Number; 19 Month : out Month_Number; 20 Day : out Day_Number; 21 Seconds: out Day_Duration); 22 23 function Time_Of(Year : Year_Number; 24 Month : Month_Number; 25 Day : Day_Number; 26 Seconds: Day_Duration := 0.0) 27 return Time; 28 29 function + (Left: Time; Right: Duration) return Time; 30 function + (Left: Duration; Right: Time) return Time; 31 function - (Left: Time; Right: Duration) return Time; 32 function - (Left: Time; Right: Time) return Duration; 33 34 function < (Left, Right: Time) return Boolean; 35 function <=(Left, Right: Time) return Boolean; 36 function > (Left, Right: Time) return Boolean; 37 function >=(Left, Right: Time) return Boolean; 38 39 Time_Error: exception; 40 41 private 42 ... -- not specified by the language 43 end Ada.Calendar;
You have seen lines 1-15 earlier and I do not belabor them. Lines 17-20 define a procedure that accepts a Time value and returns, in four out parameters, the four components that the functions in lines 12-15 return separately. The four functions and this procedure are, in object-oriented design, generally called selector operations because they return selected information from an objectin this case a Time objectwithout modifying the original object.
Lines 23-27 provide a constructor function that goes the other way: Given the four component values, Time_Of produces a time. The Seconds parameter (line 26) is provided with a default value of 0.0. If a calling program does not supply an actual parameter for this formal parameter, the default is used. If T is a Time variable, then
T := Ada.Calendar.Time_Of(7, 29, 1997);
returns a value corresponding to midnight at the start of July 29, 1997. On the other hand,
T := Ada.Calendar.Time_Of(6, 31, 1997);
is invalid because June has 30 days, and
T := Ada.Calendar.Time_Of(2, 29, 1997);
is invalid because 1997 is not a leap year. In both of these cases, Ada.Calendar.Time_Error (as defined in line 39) is raised at the point of each call; it is up to the calling program to handle the exception. I return shortly to package-defined exceptions.
Lines 29-32 define infix operators for Time values. Note that there is no operator to add two times; it is physically meaningless to add 2 oclock to 3 oclock. On the other hand, adding a Duration and a Time is meaningfulDuration represents elapsed time, and 2 oclock plus 15 minutes gives 2:15. Note that I need one operator for the Time value on the left and another for the Duration value on the left.
Finally, you see (lines 34-37) comparison operators for Time values. Time is ordered, so comparing two times is meaningful.
This quick look at Ada.Calendar has introduced constructor and selector operations and Adas style for defining new infix operators. I consider these issues in more detail later in this chapter in introducing some of my own packages.
Previous | Table of Contents | Next |