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