Guru: Aliases — Underused and Unappreciated
October 3, 2022 Ted Holt
One of the first things I learned about programming in the RPG II language was that field and variable names had to be six characters or less and they did not have to be pronounceable. I accepted this without question, as I was new to computers and figured that everything that had to do with computers was arcane and other-worldly. It wasn’t until I began work toward my computer science degree and was privileged to learn Pascal that I came to appreciate the value of longer identifier names, and of clarity of source code in general.
You don’t have to have a computer science degree to use long field names in modern RPG. Even if your database files — physical and logical — have field names of six characters or less, you don’t have to use those short names ever again in RPG programs. It is my purpose in this article to show you how to use longer, more legible field names instead.
Here’s some DDS for a physical file that (we’ll pretend) was first created in antiquity on an AS/400 from a file ported from a S/36.
A UNIQUE A R INVOICE A IVINUM 7 0 TEXT('INVOICE NUMBER') A IVDATE 7 0 TEXT('INVOICE DATE') A IVCOMP 3 0 TEXT('COMPANY NUMBER') A IVCUS# 5 0 TEXT('CUSTOMER ACCOUNT NUMBER') A IVDUDT 7 0 TEXT('DUE DATE') A K IVINUM
Notice that the first two characters of each field name are IV. This antiquated practice was common in bygone days. Each physical file had its own two-character variable name prefix so that fields from different files could not overlay each other in memory. There is no need to distinguish fields in this manner these days, but the custom endures.
DDS limits field name length to 10 characters, which is not too bad. If you reserve the first two characters of each field name to identify the file, you have eight distinguishing characters in the field names. That’s still not too bad. The compiler, of course, doesn’t care how long or short the field names are. But I care. I care because I have to read the code, and CMCRLT and CMCLRT look a lot alike.
In Code Complete, Steve McConnell mentions a study of the relationship between length of identifiers and ease of debugging in COBOL programs. The study reported that debugging effort was less when identifiers tended to have names from 10 to 16 characters long. Programs with 8- to 20-character names were almost as easy to debug.
Fortunately, it is easy to have longer field names in RPG programs. First, add the ALIAS keyword to the DDS.
A UNIQUE A R INVOICE A IVINUM 7 0 TEXT('INVOICE NUMBER') A ALIAS(INVOICE_NUMBER) A IVDATE 7 0 TEXT('INVOICE DATE') A ALIAS(INVOICE_DATE) A IVCOMP 3 0 TEXT('COMPANY NUMBER') A ALIAS(COMPANY_NUMBER) A IVCUS# 5 0 TEXT('CUSTOMER ACCOUNT NUMBER') A ALIAS(ACCOUNT_NUMBER) A IVDUDT 7 0 TEXT('DUE DATE') A ALIAS(DUE_DATE) A K IVINUM
An alias name has to be 30 characters or less for physical files defined by DDS. CREATE TABLE allows longer field names, but I’ve never needed them. Thirty characters is infinity for my purposes.
Each field now has two names: a system name (a short one), and an alias (a long one).
The nice thing about adding aliases to DDS-defined physical files is that there is no level check. You can add aliases to an existing file without having to recompile the programs that use the file. Happy day!
Once you’ve added the aliases, your RPG programs can be free from the short names of 10 or fewer characters. I say “can be” because you have to do a little work. And I really do mean “a little.” You have to add the ALIAS keyword in two places: file definitions and externally-described data structures. Let’s look at a program that uses aliases.
But first, another physical file, the customer master file. It also has aliases:
A UNIQUE A R CUSTOMER A CUCOMP 3 0 TEXT('COMPANY NUMBER') A ALIAS(COMPANY_NUMBER) A CUCUS# 5 0 TEXT('CUSTOMER ACCOUNT NUMBER') A ALIAS(ACCOUNT_NUMBER) A CUCNAM 20 TEXT('CUSTOMER NAME') A ALIAS(NAME) A CUCCLS 1 TEXT('CUSTOMER CLASS') A ALIAS(CLASS) A CUCRLM 7 2 TEXT('CREDIT LIMIT') A ALIAS(CREDIT_LIMIT) A K CUCOMP A K CUCUS#
Here’s the program. You don’t have to use free-form RPG when using aliases. I did this example in free form because that’s the way I write my code these days.
dcl-f InvHdrPF disk keyed alias; dcl-f CustPF disk keyed alias; dow *on; read InvHdrPF; if %eof(); leave; endif; chain (Company_Number: Account_Number) CustPF; if not %found(); clear Class; clear Credit_Limit; endif; // do something with the data enddo; return;
Notice the ALIAS keyword in the two DCL-F statements. Notice also that the CHAIN refers to aliases from the invoice header, and the two CLEAR operations refer to aliases from the customer master file.
And that’s all there is to it.
You can also use aliases in externally described data structures.
dcl-ds Invoice extname('INVHDRPF') qualified alias inz end-ds; clear Invoice.Due_date;
Notice that the clear refers to the alias, Due_date, not the short name IVDUDT.
Notice also that aliases don’t have to be longer than 10 characters.
One last point and I’m done. The ALIAS keyword is an RPG feature. CL cannot reference the aliases. For instance, to copy all company-one records to a temporary file, you would use a command like this one:
CPYF FROMFILE(CUSTPF) TOFILE(QTEMP/CUST001) + MBROPT(*REPLACE) CRTFILE(*YES) + INCREL((*IF CUCOMP *EQ 1))
When possible, I use SQL for input/output. SQL understands the system names and the aliases and doesn’t care which ones you use. I always use the aliases, of course. When I have to use native I/O, I qualify the files and use the aliases. Life is too short to fight with illegible source code.