No More Global Variables!
June 24, 2009 Ted Holt
Last December, I shared four ways to avoid problems caused by the use of global data in RPG programs. I mentioned that a discussion of i 6.1 (or as I call it, V6R1) data-localization features would have to wait for another day. Well, that day is here.
With V6R1, it is possible to write programs that have no global identifiers. (By identifiers, I mean variables and constants. By variables, I not only mean scalar variables, but also arrays and data structures.) You only need to change two programming practices.
First, lose the RPG cycle. It breaks my heart to think of RPG without a cycle. I learned RPG on a S/3 Model 12, did my first production work on the S/34, and later worked on the S/36. I prided myself on my understanding of the RPG cycle. But frankly, I have used so little of the cycle over the past 20 years or so, that getting rid of the rest of it is no big deal.
To create an RPG program that has no embedded cycle logic, use the MAIN keyword in the H specs. MAIN requires one argument–the name of the controlling subprocedure.
H Main(AR100) H dftactgrp(*no) actgrp(*caller) H option(*srcstmt: *nodebugio) D AR100 pr extpgm('AR100') D From 4a const D To 4a const P AR100 b D pi D From 4a const D To 4a const ... etc. ... P e
In this example, there is no RPG cycle–no detail calcs, no total calcs, no check for page overflow, no check for control breaks, no matching records, none of that stuff. When this program loads, subprocedure AR100 gets control and runs.
The second thing you must do to avoid global data is to put file declarations inside of subprocedures.
P GetCustName b FCustMasterif e k disk usropn D pi D Company 3p 0 const D Customer 9p 0 const ... etc. ... P e
In this example, the customer master file is declared within subprocedure “GetCustName,” and is not directly accessible from other subprocedures. There’s a good bit more to say about the use of files within subprocedures. That will have to wait until yet another day.
Your program source code consists of H specs, D specs for prototypes and record-format templates, and subprocedures. Subprocedures contain P specs, F specs, D specs, and C specs. The end result is a program with no global identifiers.