I spent the end of last week assisting my colleagues with a project that involved creating CL programs, and over the weekend I was asked to check someone's CL code. In both cases I was disappointed to find that while these individuals have modernized their RPG skills, their CL skills are still date back to the 20th century.
In my opinion CL is a programming language which is undervalued in IBM i circles. I have met many developers who would rather use a complicated API in their RPG code, rather than use a simple CL command. It is time for everyone to look at all the tools that are available in IBM i, rather than limit themselves to just be a "RPG programmer".
Here are some of the things I think we should all do with our CL code.
CLLE, no more CLP
RPGLE was not the only ILE capable language that came out in V3R1, in 1994. ILE CL, CLLE, joined the party at the same time.
It is easy to convert a CLP source member to a CLLE some, just change the member type. The only command that I can think of that does not convert to CLLE is the Transfer Control command, TFRCTL, which can easily be replaced by a CALL command.
If you keep your source types in separate source files, you do not have to create another source file. CLLE member go in the QCLSRC source file.
You can RTVCLSRC CLLE
One of the excuses I hear why people will not convert their source to CLLE is you cannot use the Retrieve CL Source command, RTVCLSRC. While that was valid for years, it is no longer so.
As part of IBM i 7.1 the RTVCLSRC command was enhanced to retrieve the source from CLLE programs and modules.
No more GOTO, use Do-loops
I am sure you use Do-loops in your RPG code, and shun Goto. It is time to do the same in your CL. DOWHILE, DOUNTIL, and DOFOR are all ready and waiting for you.
I cannot think of RPG without subroutines. You can do them in CL too, and the same principals apply. Rather than repeat code or call another CL program to do what you want use a subroutine.
No more nested Ifs, use Select
We have all seen blocks of code in CL of If statements where they are all executed despite only one being relevant. In 2004 V5R3 brought CL the SELECT command. It has the same functionality as the Select operation code in RPG. Use it as it will make your CL code less complicated and easier to follow.
You can define and use the equivalent of data structures in CL. It it is easier, and faster, to use them rather than substring-ing the same string out of a larger variable every time you need it.
With IBM i 7.2 several new Built in Functions, BiFs, were introduced to make it easier to do some string handling in CL. I no longer have to call a RPG program or write many lines CL code to do the following:
- Char built in function added to CL
- CL Built in Functions to Change Case
- Trim in CL and its Second Parameter
You can write, update and delete records
Someone once said to me he could not take any programming language seriously if he could not write and update a file using it. By using the Run SQL Statement command, RUNSQL, I can do all of that.
Here are examples showing how it is possible, in CL, to delete a row/record from a table/file, add a row/record, and change it:
01 PGM 02 DCL VAR(&VAR1) TYPE(*CHAR) LEN(3) VALUE('1') 03 DCL VAR(&VAR2) TYPE(*CHAR) LEN(3) VALUE('ABC') 04 RUNSQL SQL('DELETE FROM TESTFILE + WHERE F1 = ''' || &VAR1 |<''' ') + COMMIT(*NC) 05 RUNSQL SQL('INSERT INTO TESTFILE + VALUES (''' || &VAR1 |< ''',DEFAULT)') + COMMIT(*NC) 06 RUNSQL SQL('UPDATE TESTFILE + SET F2 = ''' || &VAR2 |< ''' + WHERE F1 = ''' || &VAR1 |< ''' ') + COMMIT(*NC) 07 ENDPGM
Most of the examples I have seen of procedures show RPG. It is possible to create CL procedures, and to use CL commands rather than complicated APIs to do the things CL does best.
Now you have seen that some of the biggest myths about CL have been busted. It is time to embrace modern CL and start using it in a 21st century manner.
This article was written for IBM i 7.2.