home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / programm / prog1 / chap15.txt < prev    next >
Encoding:
Text File  |  1991-07-01  |  22.1 KB  |  528 lines

  1.  
  2.  
  3.  
  4.                                                        Chapter 15
  5.                                                          PACKAGES
  6.  
  7.  
  8. PACKAGES ARE WHY ADA EXISTS
  9. _________________________________________________________________
  10.  
  11. One of the biggest advantages of Ada, over most other programming
  12. languages, is its well defined system of modularization and
  13. separate compilation.  Even though Ada allows separate compilation,
  14. it maintains the strong type checking among the various
  15. compilations by enforcing rules of compilation order and
  16. compatibility checking.  Ada uses separate compilation, but
  17. FORTRAN, as a classic example, uses independent compilation, in
  18. which the various parts are compiled with no knowledge of the other
  19. compilation units with which they will be combined.  As we progress
  20. through this material, and additional material to come later, do
  21. not be discouraged if you find many things to keep in mind when
  22. doing separate compilations.  The rules are not meant to be
  23. roadblocks, but are actually benefits for you when you are working
  24. on a large complex system.
  25.  
  26.  
  27.  
  28. LET'S LOOK AT A PACKAGE
  29. _________________________________________________________________
  30.  
  31. Examine the file named ADDERPKG.ADA for our      ================
  32. first example of a separately compiled Ada         ADDERPKG.ADA
  33. package.  A package, as the term is used in Ada, ================
  34. refers to a collection of related entities, the
  35. collection being composed of procedures,
  36. functions, variables, constants, types, subtypes, and even other
  37. packages.  In our present example, the package is composed of one
  38. type, and one procedure.
  39.  
  40.  
  41.  
  42. THE SPECIFICATION OF THE PACKAGE
  43. _________________________________________________________________
  44.  
  45. Lines 4 through 8 define the specification of the package named
  46. AdderPkg, which is actually a very simple package, and purposely
  47. kept simple for illustrative purposes.  The type MY_ARRAY is
  48. defined, as well as the procedure heading for Add_Em_Up in the
  49. specification part of the package.  The only things a user needs
  50. to know about the package in order to use it are defined in the
  51. package specification, so it becomes the interface to the outside
  52. world.  With a few defining statements, this is all the user would
  53. need to know about the package, and he could be kept away from the
  54. actual details of how the procedure does its job.  We will see more
  55. about the topic of information hiding later in this chapter.
  56.  
  57.  
  58.                                                         Page 15-1
  59.  
  60.                                             Chapter 15 - Packages
  61.  
  62. Note that anything that is declared in the specification part of
  63. the package can be used in any other package that with's this
  64. package.
  65.  
  66. We have an unconstrained array type declared in line 5 which we
  67. have not yet studied in this tutorial.  The range for the subscript
  68. is defined by the "<>", which is a box that must be filled in later
  69. when we define the actual type.  We will cover this in detail in
  70. the chapter on advanced array topics.
  71.  
  72.  
  73.  
  74. THE BODY OF THE PACKAGE
  75. _________________________________________________________________
  76.  
  77. Lines 12 through 23 give the body of the package, and it is
  78. distinguished from the specification by the reserved word body in
  79. its header, and by the fact that the procedure is completely
  80. defined here.  Anything defined or declared in the specification
  81. part of the package is available for use here, just as if it were
  82. defined at the beginning of this section.  The procedure header is
  83. redefined here in full, and it must exactly match the definition
  84. in the specification or you will get a compile error and no
  85. compilation.  There is nothing different about this procedure from
  86. any other procedure we have seen, it just happens to be in the
  87. package body.
  88.  
  89. Note that any types, variables, constants, procedures, or
  90. functions, can be declared in the package body for use within the
  91. body, but none of them are available outside of the package because
  92. they are not defined in the specification part of the package.  The
  93. variable declared in line 15 named Total is not available outside
  94. of this package and there is no way it can be referred to outside
  95. of the package without being declared in the package specification.
  96. In fact, since it is embedded within the procedure, it would be
  97. hidden anyway, but the fact remains that no entities are available
  98. outside of the package except those that are declared in the
  99. specification of the package.
  100.  
  101. Note that since the array has no defined limits, we must use
  102. attributes to define the loop range.  Even though you may find this
  103. a bit confusing, you will appreciate the flexibility found here
  104. after we study some of the more advanced topics.
  105.  
  106.  
  107.  
  108. IT CAN BE COMPILED BUT NOT EXECUTED
  109. _________________________________________________________________
  110.  
  111. This file can be compiled, but it cannot be linked and executed
  112. because it is not a complete program, it is only a package
  113. containing a type and a procedure which can be called from another
  114. program just like we have been calling the procedure Put in the
  115. Text_IO package throughout this tutorial.
  116.  
  117.                                                         Page 15-2
  118.  
  119.                                             Chapter 15 - Packages
  120.  
  121.  
  122. One other point must be made before we look at a program to use
  123. this package, the specification and the body do not need to be in
  124. the same file, they can be contained in separate files and compiled
  125. separately.  If this is the case, the specification must be
  126. compiled prior to compiling the body because the body uses
  127. information generated during compilation of the specification.
  128. Actually, even though they are in one file in this example, they
  129. are considered separately by the compiler, being compiled in serial
  130. fashion.  This file is said to be composed of two compilation
  131. units.
  132.  
  133.  
  134.  
  135. FILENAME VERSUS PACKAGE NAME
  136. _________________________________________________________________
  137.  
  138. In all of the example programs so far in this tutorial we have used
  139. the same name for the filename and the program name, or the
  140. procedure name.  This is not really necessary, but it was felt that
  141. an additional level of complexity should be delayed until later.
  142. We have arrived at the time when an explanation is needed.  When
  143. Ada compiles a program, it adds the result of the compilation into
  144. its library using the program name.  This library entry includes
  145. all information needed to link the program later with the other
  146. needed library entries.  Later when you use the linker supplied
  147. with your compiler, the linker will collect all of the necessary
  148. compiled packages and subprograms and combine them into an
  149. executable program.
  150.  
  151. In order to compile a program, it is necessary to give the filename
  152. so the operating system can find the program for the Ada compiler,
  153. but in order to link a program, the filename is no longer of any
  154. use because the name that really matters is the program name, and
  155. the program name is what the linker uses.  Ada allows identifiers
  156. to be of any arbitrary length, but your operating system has some
  157. length limit, eight if you are using MS_DOS, therefore the Ada
  158. compiler may need to somehow make up a new name if intermediate
  159. results are put into individual files.  It will be up to you to
  160. determine how your compiler stores intermediate results and how it
  161. makes up filenames for these results.
  162.  
  163. For simplicity, therefore, all program names have been limited to
  164. eight characters, and the same name is used for the filename
  165. throughout most of this tutorial.
  166.  
  167.  
  168.  
  169. NOW TO USE THE NEW PACKAGE
  170. _________________________________________________________________
  171.  
  172. The example file named ADDER1.ADA, illustrates how to use the
  173. previously studied package.  There is nothing different about this
  174. program from any other program we have used except that it uses the
  175.  
  176.                                                         Page 15-3
  177.  
  178.                                             Chapter 15 - Packages
  179.  
  180. package we defined and named AdderPkg, which it  ================
  181. acknowledges in lines 5 and 6 where it tells the    ADDER1.ADA
  182. system to with the package and to use it in the  ================
  183. program at hand.  It also uses the renaming
  184. statement in line 19 which we will discuss
  185. later.  The remainder of the program is simple, and you should have
  186. no trouble deciphering it.  The primary purpose of these two
  187. examples is to illustrate how to write a library package.
  188.  
  189. In line 17 we declare an array of type MY_ARRAY and at this time
  190. we supply the range limits for the subscript.  You may begin to see
  191. the flexibility in this method of array declaration, but we will
  192. study it in detail later.
  193.  
  194.  
  195.  
  196. THE with CLAUSE
  197. _________________________________________________________________
  198.  
  199. It is finally time for a complete definition of just what the with
  200. clause does for us.  When we with a package into our program, we
  201. are telling the system that we wish to have everything that is
  202. declared in the specification of that package available for our use
  203. in this program.  Accordingly, the system will look at the items
  204. declared in the specification for that package and every time we
  205. use one of those items, it will see that we have the correct number
  206. of parameters and that we have the types declared for each
  207. parameter correctly.  Note that this happens during compilation and
  208. explains why Ada is said to be compiled separately, but not
  209. independently of other compilation units.  In a sense, the
  210. resources available in the withed package act as though they are
  211. extensions to the Ada programming language.  Because of this, the
  212. with clause is called a context clause.
  213.  
  214. When you arrive at the linking operation, the withed packages are
  215. automatically added into the executable file, as are any other
  216. packages that are withed by the package you have explicitly told
  217. the system to with into your program.  Note that the package named
  218. STANDARD is automatically withed into every Ada program,
  219. subprogram, or package.  The package named STANDARD defines many
  220. of the predefined entities such as INTEGER, BOOLEAN, FLOAT, etc.
  221.  
  222. In a large program, it is possible to with the same package several
  223. times since it is used in several packages.  You can be assured
  224. that only one copy of the package will be included during the
  225. linking operation.  Multiple copies will not be stored.
  226.  
  227. One other point must be made before leaving this topic, and that
  228. is the fact that all with clauses must be at the beginning of the
  229. program or package.  There is a good reason for this.  The
  230. dependent packages, and hence the overall program structure must
  231. be given at the beginning of each package making it easy to
  232. ascertain the overall structure without being forced to search
  233. through the entire listing for each package.
  234.  
  235.                                                         Page 15-4
  236.  
  237.                                             Chapter 15 - Packages
  238.  
  239.  
  240. THE use CLAUSE
  241. _________________________________________________________________
  242.  
  243. The use clause in Ada allows you to use a shorthand when naming
  244. procedures, functions, variables, etc, from a package.  Instead of
  245. using the extended naming convention, or the so called "dot"
  246. notation, and including the package name followed by the procedure
  247. name, dotted together, you can simply use the procedure name and
  248. let the system figure out what package it is coming from.  In most
  249. of the programs we have studied so far, we have included the
  250. Text_IO package in a use clause.  If the use clause were omitted
  251. we would have to identify the package in each use of the procedures
  252. used.  Put("This is Ada"); would have to be changed to read
  253. Text_IO.Put("This is Ada");, which clutters up the listing a bit
  254. but removes all ambiguity.
  255.  
  256. Because it is possible to get a different procedure than the one
  257. you are expecting under very unusual conditions of overloaded
  258. procedure names, the use of the use clause is falling into some
  259. disrepute in the software engineering literature.  Without the use
  260. clause, you are forced to type in additional information for each
  261. procedure call, but it leads to no ambiguity and therefore follows
  262. the basic premise of Ada that a program is written once but read
  263. many times.  The extra keystrokes are worth the trouble to include
  264. them.
  265.  
  266. Use of the use clause is a matter of personal taste or possibly a
  267. style dictated by a project style guide.
  268.  
  269.  
  270.  
  271. RENAMING A PROCEDURE
  272. _________________________________________________________________
  273.  
  274. A procedure can be renamed in order to reduce the length of the
  275. identifier, especially if a rather long extended name is required.
  276. It may be better to use a more descriptive name for the actual use
  277. of a generic or general purpose procedure.  The method of renaming
  278. is illustrated in lines 19 and 20 of this program.  Of most
  279. importance is the fact that the entire list of formal parameters
  280. must be repeated.  This is done so that the definition of the new
  281. procedure name is complete and should be of help during program
  282. debugging.
  283.  
  284. Use of the new name, which is of course only a synonym and not a
  285. new procedure, is illustrated in line 35 of this program.
  286.  
  287. If you compiled the previous file, you can compile, link, and
  288. execute this one to see that the system knows how to link the two
  289. together.
  290.  
  291.  
  292.  
  293.  
  294.                                                         Page 15-5
  295.  
  296.                                             Chapter 15 - Packages
  297.  
  298. COMBINING FILES
  299. _________________________________________________________________
  300.  
  301. If you wish, you could combine the two files, provided you appended
  302. the second file to the end of the first.  The compiler would then
  303. compile all three in succession, after which you could link the
  304. results, and execute the result.  The library files must be
  305. compiled first so that the compiler can check the types in the
  306. procedure call to see that they agree, so putting them before the
  307. calling program conforms to this rule.  If you did put them in a
  308. single file, you would still need the statements in lines 5 and 6
  309. to tell the system to with and use the library file defined earlier
  310. in the file, because the compiler would consider them to be three
  311. separate compilations.
  312.  
  313.  
  314.  
  315. ANOTHER METHOD OF COMBINING FILES
  316. _________________________________________________________________
  317.  
  318. The example program named ADDER2.ADA illustrates ================
  319. another way to combine the last two files, in       ADDER2.ADA
  320. this case including the package in the           ================
  321. declaration part of the program.  The
  322. specification part of the package is in lines
  323. 15 through 19, and the body is in lines 27 through 38.  In this
  324. case, a new type is defined between the two parts to illustrate
  325. that it can be done.  Since the package is compiled as a part of
  326. the main program, it does not have to be mentioned in a with
  327. statement.  The compiler knows that it is a part of the program,
  328. but the use must be mentioned to tell the system where to get the
  329. procedure name and the type.  Of course the use can be omitted and
  330. the extended naming convention used for all references to the
  331. package.
  332.  
  333. Even though the body is defined after the variable New_Array is
  334. declared in line 23, this variable is not directly available for
  335. use in the body, because the package structure effectively builds
  336. a strong wall around the enclosed statements, and nothing can get
  337. in or out.  The only inputs to and outputs from the body are those
  338. defined in the specification part of the package.  Of course the
  339. variable New_Array is available to the procedure because it is
  340. passed in as a parameter, but is not directly visible.
  341.  
  342. One other difference occurs here that is different from the last
  343. two files.  This embedded package is not available for use by any
  344. other program, because it is enclosed within this program, and is
  345. not therefore a library package.  The entire file contains only one
  346. compilation unit.
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.                                                         Page 15-6
  354.  
  355.                                             Chapter 15 - Packages
  356.  
  357. ORDER OF DECLARATIONS
  358. _________________________________________________________________
  359.  
  360. This is a fine point, but a very important point if you get a
  361. compile error that you do not understand.  If you were allowed to
  362. include a variable declaration after you declare a procedure, it
  363. is possible for the tiny variable declaration to get lost, or at
  364. least hard to find in the listing.  The designers of Ada decided
  365. to force you to put the little things first and the bigger things
  366. last by making a rule that says, "No variable, constant, type, or
  367. subtype can be declared in any declaration block following the
  368. declaration of a procedure, function or package body."  It may be
  369. an unnecessary rule, but it does exist and is checked by all
  370. validated Ada compilers.
  371. You should compile and execute this program and you will see that
  372. it truly is identical to the previous two files combined.
  373.  
  374.  
  375. ANOTHER KIND OF SEPARATE COMPILATION
  376. _________________________________________________________________
  377.  
  378. The example file named ADDER3.ADA illustrates    ================
  379. still another method of separate compilation.       ADDER3.ADA
  380. This program is identical to the last except     ================
  381. that the package body is removed to a separate
  382. file for separate compilation, and is called a
  383. stub.  The statement in line 27 indicates to the compiler that the
  384. body will be found elsewhere.  Although this illustrates separate
  385. compilation of a package body, the same method can be used for
  386. separate compilation of a procedure.  This could be used if you
  387. wished to remove a large procedure from the logic defined here to
  388. make it more manageable.
  389.  
  390. The separately compiled body is found in the     ================
  391. file named ADDERSTB.ADA, which begins with the     ADDERSTB.ADA
  392. reserved word separate which indicates that this ================
  393. is a stub.  The main program, or whatever other
  394. package, procedure, or function, that uses this
  395. stub is defined in parentheses following the reserved word separate
  396. to tell the compiler where this is used.  This stub cannot be
  397. called or used by any other program, because it is in truth part
  398. of the program Adder3, not a general purpose program.  Any
  399. variables, types, procedures, etc, that are available for use at
  400. the point where the stub is used, are available at the point where
  401. the stub is defined.  The stub therefore has the same environment
  402. as the environment existing at the point of use, in this case line
  403. 27 of ADDER3.ADA.
  404.  
  405.  
  406. ORDER OF COMPILATION FOR THE STUB
  407. _________________________________________________________________
  408.  
  409. Since all of the variables, types, etc must be made available to
  410. the stub, the using program must be compiled before the stub itself
  411.  
  412.                                                         Page 15-7
  413.  
  414.                                             Chapter 15 - Packages
  415.  
  416. is compiled.  After both are compiled, the program can be linked
  417. and executed.  You should compile ADDER3.ADA first, then
  418. ADDERSTB.ADA should be compiled, and finally ADDER3 should be
  419. linked.  You will then have an executable ADDER3 program.
  420.  
  421.  
  422.  
  423. ORDER OF COMPILATION IS NOT MYSTERIOUS
  424. _________________________________________________________________
  425.  
  426. The example files included with this chapter are intended to
  427. illustrate to you the required order of compilation in a meaningful
  428. way, not as a group of rules to be memorized.  If you understand
  429. the dependencies of files on one another, the order of compilation
  430. will make sense, and you will be able to intelligently arrange your
  431. programs to use the Ada type checking between the various
  432. separately compiled files.  Remember that Ada, unlike Pascal, was
  433. designed to allow the development of huge programs that require
  434. separate compilation facilities, and yet retain the strong type
  435. checking between modules.
  436.  
  437.  
  438.  
  439. A PACKAGE WITH AN INITIALIZATION PART
  440. _________________________________________________________________
  441.  
  442. The example file named ADDER4.ADA illustrates    ================
  443. one more feature of a package.  This program is     ADDER4.ADA
  444. nearly identical to the first program in this    ================
  445. chapter.  Both files which comprise the first
  446. example program have been incorporated into a
  447. single file for ease of compilation, and the variable named Total
  448. has been made global within the package.  Since it is global within
  449. the package, it can be referred to by any subprogram in the package
  450. or in the initialization section as illustrated in lines 23 and 24.
  451. This section is optional but can be included in any package.
  452.  
  453. Note that the initialization section is only executed once, at load
  454. time.  For that reason, this program will not operate exactly as
  455. the first one did.  The result that is output is identical in both
  456. cases, but the additional calls will not produce the same result
  457. because the variable Total is not cleared to zero during each call
  458. in this example program as it is in the first example.  The
  459. initialization section only initializes the variable once, and it
  460. is impossible to call this section of code from within the
  461. executable part of the package.
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.                                                         Page 15-8
  472.  
  473.                                             Chapter 15 - Packages
  474.  
  475. PROGRAMMING EXERCISES
  476. _________________________________________________________________
  477.  
  478. 1.   Remove the package body from ADDER2.ADA and make it a stub.
  479.      Compile the two resulting files in the correct order and link
  480.      and execute the resulting program.
  481.  
  482. 2.   Remove all use clauses from the program named FORMATS.ADA in
  483.      the last chapter, and prefix the I/O procedure calls with the
  484.      proper package names.  It should be clear to you that there
  485.      can be no naming conflicts after this is done.
  486.  
  487. 3.   Change the name of the two compilation units in ADDERPKG.ADA
  488.      without modifying the filename, and modify ADDER1.ADA to
  489.      correspond to the new package name.  Use a name that contains
  490.      more characters than your operating system permits for a
  491.      filename.  Compile each file and link them together to result
  492.      in an executable program.
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.                                                         Page 15-9