Modularization is key to reaping the benefits of ILE. It is the major factor in cutting development time and increasing programmer productivity -- the more effective the modularization, the more productive the programming staff. But it's important to arm yourself with a reliable method when modularizing your applications.
In part 2, we looked at a detailed code example of modularizing an application. Let's now wrap up with a couple of simple tips you should be careful not to overlook.
Put procedure prototypes in a /COPY member (RPG only)
When using prototyped procedures in RPG, as we did in our example in part 2, put the prototypes in a /COPY member. Include the member in both the source member where you define the procedures and in any member that uses the procedures. This drastically reduces typing and eliminates a source of errors. And, if you later change a procedure interface (e.g., add a new parameter), you will not have to update the prototypes in each of the calling members (since there are none); although, you may have to update the calls to the procedure to reflect the change.
We did this with the prototypes for the SQLSetup and SQLCleanup procedures. The prototypes are in the file called #SQLCLIXTR (see
Don't forget about data
Global variables are often frowned upon and usually for good reason. They can make code confusing, hard to follow, and when overused tend to lead to "buggy" code. But, if you have used RPG for any length of time, you are quite familiar with them and used to using them because every variable in the old RPG (a.k.a., OPM RPG or RPG III) is global.
Things are different in COBOL and ILE RPG. These languages support local and global data. A local data item can be accessed only from within the procedure in which it is declared. This prevents other procedures from inadvertently modifying the data item, thus, reducing bugs.
However, there are some situations where global data is preferable -- not all data, just a variable or two. For example, if a number of different procedures all use the same data item and it is not global, you must pass that data item to every procedure. This increases the complexity of the procedure interfaces, which should be avoided. A solution is to declare the data item as global so that every procedure has access to it. A good example of this is a variable that keeps track of a counter. And, remember to use the exportand import keywords when applicable (and consider putting the import definitions in a /COPY file).
Extra Tip: To lessen the likelihood of a procedure inadvertently modifying a global variable, use some kind of identifier to indicate that a variable is global. For example, use a "G_" or "G-" prefix (or just 'G' if you use mixed-case names).
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years' experience programming for and managing AS/400-iSeries systems.