|
Thanks Scott and everyone else but I think I have been misunderstood.
I apologise for not being clear enough.
The DS IS declared with a copy book as you advise, Scott in Module 3.
Module 2 pulls in this declaration like this :
/DEFINE COPY_PROTOTYPE
D/COPY QRPGLESRC,MODULE3
/UNDEFINE COPY_PROTOTYPE
This copies all the prototype definitions of exported procedures in module 3 like this :
* Exported procedures.
D Module3_procedure1 PR
D A_DS LIKE ( MyDS )
/COPY MYDS
D Module3_procedure2 PR
/IF DEFINED (COPY_PROTOTYPE)
/EOF
/ENDIF
* Non exported procedures.
D Module3_procedure3 PR
So when we need to call an exported procedure, unfortunately we end up with the protoypes of ALL the exported procedures, not just those that are used.
Now, you can see module 2 will also have the DS declared in module 3.
Module 1 will pull in all the prototypes for Module 2 like this :
/DEFINE COPY_PROTOTYPE
D/COPY QRPGLESRC,MODULE2
/UNDEFINE COPY_PROTOTYPE
In the code imported, we get the procedures exported from module 2
+D Module2_procedure1 PR
+D Module2_procedure2 PR
+D A_DS LIKE ( MyDS )DS
Procedure 2 is not used but imported all the same.
Module 1 will not compile because MyDS is not declared.
I realize there is a problem perhaps with the way we import our prototype definitions.
I'd be interested to know how others include these definitions.
-----Message d'origine-----
De : midrange-l-bounces@xxxxxxxxxxxx [mailto:midrange-l- bounces@xxxxxxxxxxxx] De la part de Scott Klement
Envoyé : mercredi 27 février 2008 20:17
À : Midrange Systems Technical Discussion
Objet : Re: Service programs suck
With all due respect, this has nothing to do with service programs. If you did the same thing with dynamic program calls in RPG III, you'd have the same problem.
Now say you have the same scenario you described, except you're using *PGMs instead of *SRVPGMs. So you have a PGM1 (to replace mod1, proc1 from your example) , PGM2 (to replace mod2, proc1), PGM22 (replaces mod2, proc2) and PGM3.
To make sure you use the parameters consistently, you create the following copy book:
C PLIST2 PLIST
C PARM PARM1 90
C PARM PARM2 14
C PLIST22 PLIST
C PARM PARM3 50
C PARM PARM4 10
C PLIST3 PLIST
C PARM PARM5 12
C PARM PARM6 25
Just as in your example, PGM1 calls PGM2. PGM2 calls PGM22. PGM22 calls PGM3. You decide to modify PGM3 to accept a data structure. So you change the PLIST3 in the above copy book to look like this:
C PLIST3 PLIST
C PARM PARM5 12
C PARM PARM6 25
C PARM MYDS
Then, in PGM22 you code it like this:
IMYDS DS
I 1 4 FLD1
I 5 14 FLD2
/COPY copybook
C CALL 'PGM3' PARM3
It causes the exact same problem. PGM1 will no longer compile because it uses the same copybook, and doesn't have the definition for MYDS.
The problem has nothing whatsoever to do with whether you use a service program or RPG IV or anything.
The problem is that you've defined a parameter list (prototype) that
DEPENDS ON the definition of a data structure. In other for programs
to use those definitions, the definition for that data structure MUST be available in all programs that use the copy book.
Indeed, the fact that it's a data structure really doesn't matter -- you could've had the same problem with any the PARM1, PARM2, etc definitions as if you hadn't coded the definition right there on the PARM statement (above).
The solution, in all cases, is to have the definition of the variables be a PART OF THE COPY BOOK. That's the whole point behind using the copy book in the first place is to guarantee that all callers use the same definitions! If you require the callers to define some of the parameters internally, then you're defeating the purpose of using a copy
book to begin with. In my RPG III example, if every program that calls
PGM3 defines MYDS differently, then I really haven't accomplished my
goal of forcing all callers to use the same parameters, have I? The
same is true in RPG IV -- when your callers call a prototype with parameters based on a LIKE or LIKEDS keyword, then DON'T LET THOSE CALLERS SUPPLY THE DEFINITION FOR THE OBJECT THAT LIKE REFERENCES...
otherwise, each caller is (once again) defining it's own parameters.
Just like the RPG III example..
The difference between RPG III and RPG IV here is that RPG III doesn't really have a mechanism to allow MYDS to be included in the copy book.
Since MYDS belongs in the I-specs, and the PLISTS belong in the C- specs, you can't really use a copy book to define them both -- You'd have to use two separate copy books, one for I-specs and one for C-specs, which is cumbersome.
Worse, the definitions in the RPG III copy book are actual variable definitions -- they take up memory and can easily cause name conflicts.
RPG IV's prototypes don't have this problem.
Anyway, the solution is simple. Create a template data structure and put it in your copy book so that the parameter that uses LIKEDS () can refer to another definition in the copy book instead of referring to something outside of the copy book.
Change the code for all callers to define their local copies of the DS with LIKEDS against the one in the prototype so that the DS definition is only specified once.
in copy book, do something like this:
D Order_Address_t...
D ds qualified
D based(Template)
D Name 30a
D Addr1 30a
D Addr2 30a
D addr3 30a
D Order_GetShipAddr...
D pr 1n
D OrderNo 10a const
D ShipTo likeds(Order_Address_t)
Now anyone who uses that copybook will have the definition for both Order_address_t as well as the prototype! Then, they can call it like this:
/copy ORDER_H
D ShipTo ds likeds(Order_address_t)
.
.
if (Order_GetShipAddr('12345': ShipTo) = *OFF);
// handle error
endif;
It's really easy, and it solves problems.
David FOXWELL wrote:
-----Message d'origine-----
De : David FOXWELL
Envoyé : mercredi 27 février 2008 14:54 À : 'Websphere Development
Studio Client for iSeries'
Objet : Service programs suck
Hi everyone,
We have this problem with 1 procedure that calls another that calls another :
Module 1 Procedure 1 calls Module 2 Procedure 1.
Module 2 Procedure 2 calls Module 3 Procedure 1.
Module 3 Procedure 1 gets the following modification : a parameter M3P1Parm that is a DS declared LIKE another DS in the same module. Module 2 Procedure 2 is modified accordingly.
Module 3 is recompiled, no problem.
Module 2 is recompiled, the compiler imports the protoypes of all the exported procedures of Module 3 with the definition of M3P1Parm, again no problem.
Module 1 is recompiled, the compiler imports the protoypes of all the exported procedures of Module 2 : Procedure 1 that is uses, and Procedure 2 that it doesn't - PROBLEM, it doesn't know what is M3P1Parm.
Bigger problem : the policy is to systematically compile ALL the modules that use the module modified. I realise that probably raises a few eyebrows but that's the way things are!
Now, I am asked what I think of this way round the problem :
If an exported procedure contains a DS as a parameter then that procedure must have its own module.
I suggest that Module 2 should be a service program and that Module 1 would not have to be recompiled.
I am reminded that we do not use service programs as they use dynamic calls and that would mean the same as going back to RPGIII.
Any enlightenment would be greatly appreciated.
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list To post a message email: MIDRANGE-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/ midrange-l.
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/midrange-l.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 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.