|
The "Sorcerers Guide" Redbook covers procedures, converting from subroutines to sub-procedures, and a whole boatload of other stuff related to moving to RPGIV. http://www.redbooks.ibm.com/abstracts/sg245402.html In this case .. put prototypes into a separate member, and /COPY that member into the source with the procedure AND into the source where the procedure is being used. So the prototype does only exist once. Take care. On Wed, 8 Dec 2004 11:22:18 -0600, Bob Cozzi <cozzi@xxxxxxxxx> wrote: > Duane, > > Conventionally you need to have two solutions: > > 1) If a procedure is local to the module and is not EXPORTed then the > prototype is still required and can be "hard coded" in the global D spec > area of the source member. No "copybook" is required. > > 2) If a procedure is going to be used anywhere outside of the module in > which it is implemented, then the prototype should be placed into a /COPY > member and /COPY'd into both the original implementation module and any > other program/module that has a call to that procedure. > > I've seen another situation where someone illustrated how to use the same > source code to contain the implementation of the procedure and the > prototype, then depending on the result of /IF DEFINE statements, the > prototype XOR the entire source member was included. > -Hated that one too. > > My opinion is that you should standardize on the above two styles. Don't try > to get too creative with other techniques because it will only confuse > people more. Having written hundreds of thousands of lines of C and C++ > code, I can tell you, these two methodologies are the only ones I've seen > being used to any extent. > > -Bob Cozzi > > > > > -----Original Message----- > From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] > On Behalf Of Christen, Duane J. > Sent: Wednesday, December 08, 2004 11:04 AM > To: 'RPG programming on the AS400 / iSeries' > Subject: Procedure interfaces and prototypes > > I got this question from an associate today, I thought I would pass it and > my answer along for everyone: > > Okay. I need advice... > > "The procedure interface should be defined directly in the procedure, not > through a copybook. The compiler uses the prototype to verify that the > procedure interface is correct and is also used by the compiler to verify > that the calling program is calling the procedure correctly. If the > procedure and the calling programs use the same prototype from the copybook > they will always be right." > > I get this, and I get that it is the way MOST RPGers handle it. But I don't > > understand it entirely, because it means interface vars have to be > maintained in TWO places, once in the copybook and again for the procedure > interface. If, on the other hand, your copybook contains JUST the parm > definitions, that code can be included in all THREE locations, in calling > and called code (including PI defs). This eliminates dual maintenance. I > know everyone says the PI should never be changed, but get real--what do you > think????? > > My response Below: > The statement "The procedure interface should be defined directly in the > procedure, not > through a copybook." is wrong, and right. > > It is wrong if the procedure is to be a global procedure, available to be > imported into any program/sp/module. > > It is correct if the procedure is to be local to the program/sp/module. > > Lets say we have a math service program, SPMATH. In this math SP we have > some functions that other people need to access, these functions are: > add1ToVar, add2ToVar, multiplyVarBy10. > add1ToVar is in module MODA, it is exported from MODA and calls a procedure > getVarValue. > add2ToVar is in module MODB, it is exported from MODB and calls a procedure > getVarValue. > multiplyVarBy10 is in module MODC, it is exported from MODC and calls a > procedure getVarValue, it also calls a procedure multiplyVar. > multiplyVar is also in MODC, it is NOT exported from MODC. (It is not called > by any other procedure except multiplyVarBy10) > getVarValue is in MODX, it is exported from MODX. (It is called by many of > the math procedures, but it should only be called from math procedures in > SPMATH) > > This is how I would put it together: > SPMATH exports add1ToVar, add2ToVar, and multiplyVarBy10. In other words the > binding source for SPMATH contains something like this: > STRPGMEXP PGMLVL(*CURRENT) > EXPORT SYMBOL(ADD1TOVAR) > EXPORT SYMBOL(ADD2TOVAR) > EXPORT SYMBOL(MULTIPLYVARBY10) > ENDPGMEXP > > This makes the procedures add1ToVar, add2ToVar, and multiplyVarBy10 global, > available to be imported into any program/sp/module. > > The copybook for SPMATH would contain prototypes for the procedures > add1ToVar, add2ToVar, and multiplyVarBy10 and would be /COPYed or /INCLUDEd > in any program/sp/module that needed to import them. (Including the modules > that export them) > > Even though getVarValue is local to the service program it must be exported > from the module MODX, but it is not exported from the sp SPMATH because it > is not listed in the binding source so the modules MODA, MODB, MODC and MODX > would contain a copy of prototype for getVarValue, I would not have this > prototype in a copybook because it is local to the sp SPMATH. > > The module MODC would contain the only prototype for the multiplyVar, and it > would not be exported from the module because it is local to the module, > only used by the procedures in MODC. > > The procedure interface is a seperate entity from the prototype and CAN NOT > be in a copybook. If a procedure is designed correctly the interface, and > the related prototype should not change. > > If it is necessary to change a procedure interface the change can be > implemented so that it does not impact any existing code. Lets say this > procedure, PROCA, is defined like this: > > Prototype in a copybook: > procA PI > 10A Value > 10P 0 Value > > Procedure interface: > procA PI > field1 10A Value > field2 10P 0 Value > > Then lets say that we need to have another parameter field3, the interface > then would look like this: > > Prototype in a copybook: > procA PI > 10A Value > 10P 0 Value > 5I 0 Value Options(*NOPASS) > > Procedure interface: > procA PI > field1 10A Value > field2 10P 0 Value > field3 5I 0 Value Options(*NOPASS) > > In the code for the procedure PROCA you would have something like this: > > If %Parms = 3 > field3Value = field3 > Else > field3Value = 0 > EndIf > > What this does is: if 3 parameters were passed into the procedure then the > variable field3Value, which is used throughout the procedure, is set to the > value passed into the procedure. Otherwise the variable field3Value is set > to a default value which will be used throughout the procedure. > > Ok so now lets do one a little more complicated, lets say we now need to > extend the parameter field1 from 10A to 20A, there are a couple of ways to > do this but they are all ugly, this is the way I would do it: > > Prototype in a copybook: > procA PI > 10A Value > 10P 0 Value > 5I 0 Value Options(*NOPASS) > 20A Value Options(*NOPASS) > > Procedure interface: > procA PI > field1 10A Value > field2 10P 0 Value > field3 5I 0 Value Options(*NOPASS) > field4 20A Value Options(*NOPASS) > > In the code for the procedure PROCA you would have something like this: > > If %Parms >= 3 > field3Value = field3 > > If %Parms = 4 > field1Extended = field4 > EndIf > Else > field3Value = 0 > field1Extended = field1 > EndIf > > What this does is: if 3 or more parameters were passed into the procedure > then the variable field3Value, which is used throughout the procedure, is > set to the value passed into the procedure. If 4 parameters were passed then > the variable field1Extended, which is used throughout the procedure, is set > to the value passed in for the longer field1 value. Otherwise the variable > field3Value is set to a default value which will be used throughout the > procedure and field1Extended is set to the field1 value. > > This may seem rather ridiculus, and it is, but this is an example of poor > interface planning and I have done things like this in the past, some even > more rediculus. > > If you are sure, and I mean SURE that the interface will not change then > passing individual parameters like this will work just fine for the > procedure, but if you are not sure or you know that in the future there will > be the need to "add" capabilities to the procedure then you need to designe > a flexable interface like this: > > getCustomerInfo... > PI > infoBase * Value > infoFormat 10A Value > infoLength 10I 0 Value > keyBase * Value > keyFormat 10A Value > keyLength 10I 0 Value > > We can talk about this later, I need to get back to work now. > > Duane Christen > > NOTICE: This electronic mail transmission may contain confidential > information and is intended only for the person(s) named. Any use, copying > or disclosure by any other person is strictly prohibited. If you have > received this transmission in error, please notify the sender via e-mail. > > -- > This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list > To post a message email: RPG400-L@xxxxxxxxxxxx > To subscribe, unsubscribe, or change list options, > visit: http://lists.midrange.com/mailman/listinfo/rpg400-l > or email: RPG400-L-request@xxxxxxxxxxxx > Before posting, please take a moment to review the archives > at http://archive.midrange.com/rpg400-l. > > -- > This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list > To post a message email: RPG400-L@xxxxxxxxxxxx > To subscribe, unsubscribe, or change list options, > visit: http://lists.midrange.com/mailman/listinfo/rpg400-l > or email: RPG400-L-request@xxxxxxxxxxxx > Before posting, please take a moment to review the archives > at http://archive.midrange.com/rpg400-l. > > -- Tom Jedrzejewicz tomjedrz@xxxxxxxxx
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.