I am starting to use /Free coding in RPG and like the clarity and readability of the code. However I can not get my head around the replacement to using *ENTRY and a PLIST to use parameters passed in to the program. Sometimes this is passed on a call from a CL program, at other times it is a direct call from another program. For instance. I use one PLIST on *ENTRY with a parm called Alist. I then have Alist defined as a data structure with four fields: Batch (4A), InvDate (8a), Division (3a) and Payer (10a). My cheat sheet for Free by Bryan Meyers says use PR/PI definitions instead of Plist. I have looked at the IBM manuals and internet search results for defining PR/PI and I just get totally confused. Can anyone suggest a good clear guide to how to define and use PR/PI definitions?
Software/Hardware used:
V5R4 RPG
ASKED:
January 31, 2010 4:55 AM
UPDATED:
January 31, 2010 11:09 PM
This is not intended to be an “answer” but merely IMO.
I haven’t seen any really good tutorial guides. The way that I learned was simply to code a couple examples of my own until it started to make sense. My first ones were well more than a decade ago, soon after they became possible.
Start with any trivial program that receives a *CHAR 10 input parm from a CL program and places a *CHAR 10 result in an output parm. The CL verifies the result. Then extend it to become a bound procedure that returns a value in addition to the output parm. The CL won’t be more than a dozen lines and the RPG won’t have to be much more.
Create a second sample that starts as a clone of the first. Have it accept a couple numeric values and return the sum or difference as the return value. Include an input parm that directs the action to be a sum or difference.
There is no substitute for creating your own examples and having them available from then on. At any time, you can create new clones to experiment with new needs. It doesn’t take more than three or four before you have your own starter set for just about any kind of module you want to create.
Anyway, everything that you call with CALLP (Call with Prototype), either program or procedure, including the program you are writing, gets a PR. Both CALL and CALLB become CALLP. The prototype is duplicated in the calling and called programs. In the calling program, the PR replaces either the *PLIST used for the CALL or the parameter list used for CALLB, in terms of defining the characteristics of the parms.
In addition, every procedure gets a PI for itself. This replaces the *ENTRY PLIST. The PI parameter list is a replacement for any D-specs that you previously created to receive arguments.
The parameters must match between a PR and its associated PI. The match is determined by data types and lengths, as well as the order.
In most senses, that’s all there is to it.
Because a PR goes into both called and calling programs (or procedures), it may be best if a single PR is created as a /COPY member and copied wherever needed. In many sites, the associated PI is in the same member. /COPY directives are used to place the PR or PI where needed. This helps ensure that definitions always match. If they don’t, the compiler complains — mismatched parms become almost impossible.
There is much that can be accomplished with PR/PI and CALLP. Significant reduction of parameter errors is only the beginning.
But practice is where the sense of knowledge comes from. If you feel it’s necessary, I can supply a beginning sample CL and RPG procedure as a starter for you. I just don’t know of any good tutorials.
Two useful items by Jon Paris — RPG IV Subprocedures: The Basics and Subprocedure Basics: How and why to convert subroutines to subprocedures.
That’s about as good as I can do to point to useful info as you requested. If you have specific questions, I can probably give better answers.
Tom