Named Indicators
Assigning meaningful names to indicators.
There is no technical superiority to using named indicators instead of standard indicators, in either case it distills down to a true or false test. However, the use of the named indicators can remove an amount of ambiguity from the code. And, that is a good thing.
Mapping Indicator Array
Indicator Array Standalone indicators d indPtr s * inz( %addr(*in) ) * define named indicators d indicators ds 99 based( indPtr ) d ScreenChange n overlay( indicators : 22 ) d SflControl n overlay( indicators : 50 ) d SflDisplay n overlay( indicators : 51 ) d SflInitialize n overlay( indicators : 52 ) d SflClear n overlay( indicators : 53 ) d SflEnd n overlay( indicators : 54 ) d SflDelete n overlay( indicators : 55 ) d SflNxtChange n overlay( indicators : 58 ) d SflMSGQdisplay... d n overlay( indicators : 59 ) sflControl = *ON ; IF sflrcn > 0 ; sflDisplay = *ON ; ENDIF ; WRITE SC032001 ; EXFMT SC0320C1 ;
Evolving from RPG II, where conditioning indicators were the sole method of decision logic, indicators moved from the line level to the op code level in RPG III. Shortly thereafter, programmer design tried to move beyond indicators and there use declined in RPG/400. But with the advent of program-defined Boolean variables, indicators show some signs of making a return in RPG. Though it is not the necessity it once was the data definition (D) specs provide support for Boolean variables. The following describes named indicators, which may be used in the same manner as the *IN indicators.
0073.00 D ReturnRequested... 0074.00 D S n 0075.00 D ScreenChanged... 0076.00 D S n 0077.00 D RecordLocked S n 0078.00 D ErrorFound S n . . . 0094.00 DOU ReturnRequested 0095.00 IF not ReturnRequested 0096.00 ScreenChanged = *OFF 0097.00 EXFMT RATER102 0098.00 ScreenChanged = *IN22 0099.00 EXSR @SaveCursor 0100.00 SELECT 0101.00 WHEN KeyPressed = F8 0102.00 ReturnRequested = *ON 0103.00 EXSR @ProcessEntry 0104.00 WHEN KeyPressed = F12 0105.00 ReturnRequested = *ON 0106.00 ENDSL 0107.00 ENDIF 0108.00 ENDDO
Since named indicator variables are indicators, they may be tested on IF statements without a comparison to a value, but rather stated as a condition, (IF/IF NOT). The following code demonstrates the how a Boolean variable might be used to present code that is more legible and more explicit than the example in Fig. 1. Though not perfect, the revised code using named indicators, is far easier to interpret. The statement IF ErrorFound in Fig. 2 is definitive, if generic. With the use of named indicators, the statements can be made as explicit as necessary to describe the error condition. Notice the IF RecordLocked statement. It is easily apparent that a record may be updated if the record if a lock has been granted. Downstream, testing whether a rate was added on the file is a simple test; IF RateAdded. Named indicators make for simpler, more maintainable code.
0044.00 D CustomerRateNotFound... 0045.00 D S 1n 0046.00 D OrderRateNotFound... 0047.00 D S 1n . . . 0143.00 IF CustomerRateNotFound AND OrderRateNotFound 0144.00 CHAIN (i_opcm : k_swcat : k_swcode) SWCODEP 0145.00 IF not %found(SWCODEP) 0146.00 CHAIN (k_swcm : k_swcat : k_swcode) SWCODEP 0147.00 ENDIF 0148.00 mi_rate = swnum1 0149.00 mi_basis = %trim(swchr1) 0150.00 ENDIF 0151.00 i_rate = mi_rate 0152.00 i_basis= mi_basis 0153.00 i_miles= milesbilled 0154.00 ENDIF Fig. 3
The example, Fig. 3 illustrates how the use of named indicators for specific conditions can prove useful in interpreting code. The code snippet is attempting to retrieve a rate and rate basis, because, no customer rate was found and no order rate was found. It brings a degree of clarity to the decision that isn’t available with the use of standard indicators