September 5, 2012 Paul Tuohy
One of my favorite benefits that comes from speaking at conferences is the great questions that get asked of me and other speakers. Even if we can answer the question, be assured the next time we’re gathered with colleagues over a cup of coffee (or other beverage of choice), one of us will say, “I was asked an interesting question at my last conference. . .”
At the last RPG & DB2 Summit, I was having coffee with Susan Gantner and Barbara Morris, when Susan uttered those intriguing words. The ensuing conversation didn’t result in a change to the answer Susan had given to the asker of the question, but it did give rise to a discussion on the concept of coding a solution that the compiler does not support in a current release but does support in a future release.
Why would you want to do this? Usually, the aim of language enhancements is to make coding easier. How often have you looked at old, old code and wished you had the time to change a cumbersome method with the latest greatest Built In Function (BIF)? Time is usually the problem. It’s not just a simple matter of updating that one piece of code. You would have to check the rest of the program to make sure that other corresponding code does not need to have changes made.
The idea of future coding is that you code both the solutions at the same time and let the compiler determine which set of code should be used.
Let’s look at the question that started our discussion.
The question Susan was asked was in relation to using the %LOOKUP() BIF to perform a lookup on a sub-field of a data structure array. Unfortunately, this was a feature that was not introduced until V7R1 and the questioner was working on a V6R1 system.
The Prior to V7R1 Solution
Prior to V7R1, to perform a lookup on a sub-field of data structure array required some playing around with pointers. The technique is as follows (refer to the letters in the piece of code following this list):
(A) d myDSArray Ds qualified dim(4) d a 2a d b 2a (B) d myDSMap_p s * inz(%addr(myDSArray)) (C) d myDSMap Ds qualified based(myDSMap_p) (D) d allData 4a dim(%elem(myDSArray)) (E) d allA 2a overlay(allData) d allB 2a overlay(allData: *next) d i s 10i 0 /free // Assign values to array here (F) i = %lookup('ee' : myDSMap.allA); dsply i; *inLR = *on; /end-Free
Code 1: %LOOKUP on a DS array prior to V7R1.
Not the prettiest of pictures, and (as is always the case with pointer) prone to accidental mishap. It is what the questioner was doing, which is why they asked the question.
The V7R1 Solution
Things became a lot easier in V7R1, in that there is no longer the requirement to use pointers, or to have the overlaying data structure, defining or using the corresponding sub-arrays. Instead, we can just reference the data structure array sub-field in the %LOOKUP operation, as shown at (A) in sample code 2 below.
d myDSArray Ds qualified dim(4) d a 2a d b 2a d i s 10i 0 /free // Assign values to array here (A) i = %lookup('ee' : myDSArray(*).a); dsply i; *inLR = *on; /end-Free
Code 2: %LOOKUP on a DS array in V7R1.
Now that is a lot easier! And that brings us to the concept of future coding.
Future coding is where, even though I am on an earlier release of the operating system, I want to include the code that should be used in a future release of the operating system. In other words, I want to write a program that contains both the coding solutions shown in code 1 and code 2: the solution to be used to be determined by the compiler.
An important point to bear in mind is that I cannot yet test my future code.
To achieve our goal, we make use of the predefined Target Release condition in conditional compiler directives. The Target Release condition is in the format: *VnRnMn.
The next piece of code shows our new program:
d myDSArray Ds qualified dim(4) d a 2a d b 2a (A) /IF NOT DEFINED(*V7R1M0) d myDSMap_p s * inz(%addr(myDSArray)) d myDSMap Ds qualified based(myDSMap_p) d allData 4a dim(%elem(myDSArray)) d allA 2a overlay(allData) d allB 2a overlay(allData: *next) (A) /ENDIF d i s 10i 0 /free // Assign values to array here (B) /IF DEFINED(*V7R1M0) (C) DANGER!!! THE V7R1M0 CODE HAS NOT BEEN TESTED. IT MUST BE TESTED BEFORE COMPILING UNDER V7R1M0 OR LATER FOR THE FIRST TIME. i = %lookup('ee' : myDSArray(*).a); (B) /ELSE i = %lookup('ee' : myDSMap.allA); (B) /ENDIF dsply i; *inLR = *on; /end-Free
Code 3: Future coding prior to V7R1.
Give it a try, it might make your life a little easier further down the road and go a long way toward keeping your code up to date!
Paul Tuohy is CEO of ComCon, an iSeries consulting company, and is one of the co-founders of System i Developer, which hosts the RPG & DB2 Summit conferences. He is an award-winning speaker who also speaks regularly at COMMON conferences, and is the author of “Re-engineering RPG Legacy Applications,” “The Programmers Guide to iSeries Navigator,” and the self-study course called “iSeries Navigator for Programmers.” Send your questions or comments for Paul to Ted Holt via the IT Jungle Contact page.