The procedures we've done up to this point have been internal. Although they are interesting, they really don't provide much more benefit than subroutines. If we want to use a procedure in more than one program we still need to replicate it, which create the same maintenance issues as we had before.
We could put the procedure in a copy member and include it in the programs where we need it with the /COPY statement. Because of localized variables, procedure copybooks have a distinct advantage over copybook subroutines. We don't need to be nearly as careful with our field naming conventions, and typecasting will allow us to be much more lenient in how we pass parameters.
If we look at our summary table of the advantages of the various code re-use techniques, it now looks like this:
We can see that internal procedures are slightly more flexible when compared to subroutines. This is primarily because of the automatic typecasting of passed parameters.
Also, we can see that we procedure copybooks compare favorably to subroutine copybooks. This is also because of typecasting, but also because of localized variables and importing/exporting fields.
None of these methods compare favorably however, with the maintainability of externally called program. If an internal procedure needs to be changed, all source member that contain that procedure must be changed. If a procedure copybook is changed, all programs that use it must be re-compiled in order to see the new changes.
Externalizing procedures is the first step to creating an environment that offers the best of both worlds.
Once you've create internal procedure, externalizing them is not difficult at all. As an example we're going to externalize our IsWorkday procedure with the following steps:
Using a copybook member for Prototypes
Notice step 5 above requires you to code the Procedure Prototype in the externalized procedure source member. The prototype is also required in all programs that will use the procedure.
In keeping with the spirit of minimizing the work required to code and use procedures, and keeping them as turnkey as possible, it is a good idea to code procedure prototypes in a separate source member and including them with the /copy statement in programs that need to use the procedure.
You may even want to consider maintaining a single source member that contains prototypes for all the procedures in your application system. Declaring a prototype in a program does necessarily include the procedure(s) in your end program. It only enables your program to use those procedures. Even if you have a hundred or more procedure prototypes defined in a copy member, the overhead will be minimal. The compile listing will however be significantly larger.
Lowest Common Denominator
Recall from our conceptual discussion of procedures that ideally we want to reduce all procedures to their lowest usable function. These functions should then be re-used when needed, rather than re-written.
If we breakdown our IsWorkday procedure, we realize that it logically contains two different functions - one to determine the day of week, and one to determine if a date is a workday.
Having a function to determine a date's day-of-week, in addition to if it is a workday, would probably be helpful. Therefore, now that we're beginning to externalize procedures and create a library of utilities, it makes sense to extract the day-of-week function from the IsWorkday procedure.
Our complete source member with both procedures now looks like this:
Notice that we used the EXPORT keyword on both procedures. Also notice how compact the IsWorkday procedure is now. We don't need to do any error checking in IsWorkday anymore as it is done now in DayOfWeek.
There are many additional procedures that we may want to add, based on the DayOfWeek procedure. For example, DOWText (day of week text) could easily be created to return the day of week in it's text format (Sunday, Monday, etc). You may also want to create a procedure DOWAbbr that returns the day of week abbreviated text (Sun, Mon, etc) as well as procedures to test a date for each day of the week (IsSunday, IsMonday, etc). These utilities are now very simple to write now that we have the DayOfWeek procedure.
Send mail to firstname.lastname@example.org
with questions or comments about this web site.
Last Modified: September 06, 2000