Sometimes the advantages of "modularization" can seem counter-productive. For instance, RPG fields that were once...
automatically global and could be used by any subroutine in the program are now local to the module and can be used only in the module in which they are declared.
Normally, this "localization" is an advantage because it keeps the declaration of variables near where they are used. However, if two modules need to use the same variable, that variable must be passed between modules in the form of a parameter. That can lead to excessive parameter passing, which decreases CALL-operation performance.
How to define external variables in ILE RPG
Fortunately, there is a way to specify external variables in ILE RPG (an external variable is very similar to a global variable). The RPG keywords Export and Import enable the programmer to respectively define and declare a particular field as external.
The EXPORT keyword is used on the D-spec to define an external variable. If another module needs access to the variable, an identical D-spec is put in that module with any and all keywords replaced by the single keyword IMPORT. The IMPORT keyword tells the compiler that the variable is defined in another module, so the compiler will just put "placeholders" when it comes across the variable in the code. These placeholders will later be replaced by the binder with the location of the actual exported variable.
Definition vs. declaration
Two terms are important when discussing external variables: declaration and definition.
A variable is declared with a D-spec. It simply tells the compiler the type and length of the variable, but no storage is allocated. A D-spec with the Import keyword is therefore a variable declaration. The variable is declared with the type and length, but storage is not allocated for it because the storage will be in the exporting module.
A variable is also defined with a D-spec. The definition of a variable is very similar to a declaration except storage for the variable is allocated. A D-spec with the Export keyword is a variable definition. It also happens to be a declaration.
Many times these two terms are interchangeable. That's because for local variables (i.e., variables without the EXPORT/IMPORT keywords), there is only one D-spec for the variable and it is both the definition and the declaration, so we usually don't make any distinction.
The sample code EXP_IMP0.RPG and EXP_IMP1.RPG shows two modules EXP_IMP0 and EXP_IMP1. The variable Var1 is defined in module EXP_IMP0. (This is also a declaration for this module.) The EXPORT keyword means that other modules in the program can access the variable if they declare it with the IMPORT keyword.
To test these simple modules, first compile them with the CRTRPGMOD command (option 15 in PDM). Then bind the two modules to create a program using the following command:
/EXP_IMP) MODULE( /EXP_IMP0 /EXP_IMP1)
When to use external variables
Although some may argue that global variables (as well as GOTOs) are taboo, there are many situations when global variables are not only appropriate but are probably the best solution. Unfortunately, deciding whether to make a variable external is not always black and white.
A test we like to use is to ask yourself whether the variable in question has an impact on the entire -- or nearly entire -- program or just on a few procedures/modules. If the variable has an influence on the entire or nearly entire program, it should probably be defined as external.
For example, in a print program where many modules perform the printing and need to know the dimensions of the page. The dimensions are better suited as external variables instead of passing them as parameters among all the modules. On the other hand, a graphics routine that draws a line between two points should accept the coordinates of the two points as parameters instead of external variables.
Another good example of an appropriate use of an external variable is a field that contains the current date in a format that can be used for date comparison operations. The defining module (i.e., the exporting module) is responsible for initializing the variable and then any module in the program can use the variable if it needs to do a date-comparison against the current date.
When deciding whether to make a variable external, keep in mind the two main benefits of modular programming: reusability and breaking up large applications into more manageable pieces. External variables are usually more appropriate among modules that fit into the latter category. That is, a module or procedure that is designed to be used by many programs (like a draw-line routine) generally should not rely on the use of external variables.
Heads-up about declarations
Many RPG D-spec keywords are valid only on variable definitions and not on simple declarations. For example, the INZ keyword can be used only on a variable definition because variables can be initialized only by the module in which their storage is allocated. The sample code EXP_IMP2.RPG illustrates some common mistakes. (This example assumes an attempt is made to bind this module with the other two modules -- EXP_IMP0.RPG and EXP_IMP1.RPG.
External variables in other languages
In COBOL, you can use the EXTERNAL clause on 01-level data items. That defines the data item as external. Any subfields (i.e., subordinate data items) are automatically external also. The C language also has external variables. Moreover, external variables can be shared between the C, COBOL and RPG languages.
The table below summarizes the external variable support for the ILE languages. A Yes indicates that an external variable can be used and shared between the languages.
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.
- Breaking down an RPG program
This user is in the process of breaking down a huge RPG program into ILE RPG. He needs to break the whole program into modules so they can make changes to one module only and then promote the changed module to production. He asks, "What areas do I need to concentrate on in terms of making the program modules independent of each other?" Search400.com expert John Brandt advises.
- Global variables with EXPORT and IMPORT keywords
There are many ways to share the information between two programs such as passing parameters, data area, data queues, etc., but there is another way to effectively and efficiently share the information -- use EXPORT and IMPORT keywords.
.z5iEaXQfE7c.0@.ee84636/149>Define global set of variables
"EricG" asks, "Is there a way to define a global set of variables and then build them into a Local Data Structure within a specific procedure so that only that procedure sees them -- without moving data between variables?" Search400.com expert John Brandt has a couple ideas, including using the EXPORT keyword to create a module that uses the variables that he wants to make global.