Bind By Slash-Copy
May 15, 2013 Ted Holt
I advise, recommend, urge, admonish, and even cajole RPG programmers to quit using subroutines and start using subprocedures instead. Yet I still hear from people who work in shops that allow the use of RPG IV (a.k.a. ILE RPG), but do not allow binding to modules and service programs. Today I offer two ways to use subprocedures that do not require ILE binding.
But first, let’s have a quick review of ILE binding of subprocedures into programs.
1. Bind by copy
The object code of the subprocedures of a module is copied into the object code of a program object. Once the program has been created, the modules are no longer needed, and may be deleted. Revising the source code and recreating the module does not affect the program.
2. Bind by reference
The object code of the subprocedures of a module is copied into a service program object. Programs bind to the service programs at run time, each time using the subprocedures in the service program as the subprocedures are at that instant. Revising the source code and recreating a module require that a service program be updated, but do not require that program objects that use the service program be updated.
If you work in a shop that does not participate in the ILE binding process, you may have given up hope of ever using subprocedures, but here are two other ways that you may be able to use them.
3. Internal subprocedures
You can put subprocedures directly into a program, between the output specifications and compile-time data. This is the simple replacement of subroutines. Whether your shop binds or not, this is the normal method you should use for subprocedures that do not need to be shared with other programs.
Instead of this:
C exsr CalcFreight C CalcFreight begsr . . . more stuff . . . C endsr
H dftactgrp(*no) actgrp('QILE') /free CalcFreight (); /end-free P CalcFreight b . . . more stuff . . . P e
Now that CalcFreight is a subprocedure, you can avail yourself of the advantages of subprocedures, notably the passing of parameters and use of local variables.
4. Subprocedures in copybooks
I call this “bind by slash-copy” because I use the /COPY or /INCLUDE compiler directive to bring subprocedure source code into a program object. Also, this method achieves the same result as bind by copy. That is, the subprocedure’s object code becomes part of the program object.
Here’s an example. First, a copybook that contains the iif function.
P iif D pi 256a varying D Condition n value D TrueValue 256a varying value D FalseValue 256a varying value /free if Condition; return TrueValue; else; return FalseValue; endif; /end-free P e
This function returns one of two values, depending on a condition. I wrote about iif a while back.
Here are snippets of a program that needs this function. Notice the /INCLUDE directive.
H dftactgrp(*no) actgrp('QILE') . . . more stuff . . . /free . . . more stuff . . . DspSex = iif (Sex = 'M': 'Male': 'Female'); DspPreg = iif (Pregnant = 'Y': 'Yes': 'No'); DspMinor = iif (Age < 21: 'Yes': 'No'); . . . more stuff . . . /end-free /include qrpglesrc,iif
If you change iif, you have to recompile the callers, but at least you don’t have to make the same modification over and over.
The ideal is to use bind by reference and internal subprocedures (methods 2 and 3). Use bind by reference for shareable subprocedures and internal subprocedures for those that don’t need to be shared. But if bind by reference is out of the question, bind by slash-copy (method 4) works in a pinch. Because I am an optimist, I am willing to settle for a less-than-ideal solution when I must.