Refactoring RPG - Part 1 The Easy Stuff
How Can RPG Be Refactored?
There are literally hundreds of books on refactoring java, but I am unaware of a single one for RPG. That leaves the details of refactoring RPG to us.
Our objective in refactoring RPG is to move the code forward by improving readability, maintainability, and removing deprecated opcodes and coding rules, without changing the external behavior of the code. Let's start with improving readability and maintainability. This can be as simple as replacing short, cryptic field names with longer, more descriptive names. For example, 'ACCTNBR' can be replaced by 'accountNumber'. Standardizing the appearance of the code will add to it's readability. A more complex form of refactoring would be to re-organize blocks of code into subprocedures and breaking up a large program into a series of smaller, distinct, reusable modules. Replacing deprecated opcodes and coding rules will keep the code fresh and will allow us to discontinue outdated coding practices.
To get started, let's focus on those refactoring tasks that we can automate. The more complex forms of refactoring RPG will have to wait for another day.
Deprecated RPGLE OpCodes
Try compiling a program with any of the following deprecated opcodes in free-format and you will get an error.
Deprecated RPGLE Coding Rules
Defining fields and data areas in the Calculation Specifications is still supported in RPGLE when using fixed-format, but not in free-format. Even if you are not currently coding for free-format, it would be a good habit to begin moving these declarations out of the Calculation Specifications and into the Definition Specifications.
We need some practical ideas for achieving our objective. Here is a [partial] list of things that could be done to refactor RPG:
Maybe you can think of others, or maybe you would omit some of these from your list.
From here on we will be creating some programs (and a command) to automate some of these code refactoring ideas.
This first of four article installments will implement the simple reformatting ideas, creating our base Refactor RPG tool. The tool will be coded in CMD, CLLE, and Free-Format RPG. Each installment I will keep adding to the Refactor RPG command until it includes most, if not all of the items listed above. Like bread crumbs left along a trail, each installment of this article will lead a programmer further along the path of building our own tool to automate [at least in part] the Refactoring of RPG.
I propose we start off with the simple stuff and progress to free-format. Here is 'The Plan':
Installment 1 (this one): Create a REFACTOR command to do the easy stuff.
Installment 2 (next one): Convert MOVE's and arithmetic opcodes (Z-ADD, Z-SUB, ADD, SUB, MULT, DIV) to EVAL's.
Installment 3: Change *ENTRY PLIST to a procedure interface and replace program calls with prototyped procedure calls.
Installment 4: Convert from fixed-format to free-format.
The Easy Stuff
The parameters of the REFACTOR command ( Figure 1 ) provide control over the refactoring items that are carried out. The default is to do them all. Set the ones you do not like to *NO. The source code for this command along with the source for all the objects needed to make the REFACTOR command work are here in the figures of this article. The source member to be refactored should already be RPGLE. If it is not, then you should use the IBM provided CVTRPGSRC command to convert if from RPG to RPGLE. One gotcha you should be aware of is that an RPGLE line is 20 characters wider than the same RPG line, so make sure to use a target source file that has a RCDLEN of at least 112.
The CLLE command processing program for the REFACTOR command is CSC8801 ( Figure 2 ). There is nothing particularly magical here. A couple of file overrides, then it calls RPGLE program CS8801. That is where we will focus our attention.
Program CS8801 ( Figure 3 ) will loop through the source code to be refactored. As each line of code is processed (in the srFormatLine subroutine), a procedure will be called to implement each of our refactoring items. The program will decide if the source code line is to be changed and retained, or if it is to be discarded. You may be asking yourself why we would discard a line of code, so I will explain. Some programming techniques have been deprecated. For example, the data area definitions have been moved to the definition specifications, so the calculation specifications where data areas are defined can be discarded. Only lines of code that are no longer needed will be discarded.
Before looping through the code and doing the refactoring, some prep work needs to be done. In the spLoadRemaps subprocedure, we will read in the CSPREMAP file ( Figure 4 ) into a pair of arrays: FromVal and ToVal. These arrays are used later (in the spSetOpCode subprocedure) to convert the opcodes to the desired case (upper, lower, or mixed it's your choice). We will search the FromVal array for the opcode, and then replace it with the properly cased opcode in ToVal. The second file, CSPFIELDS ( Figure 5 ), eventually will contain information on all fields used in the source code to be refactored. To build CSPFIELDS, we will need to make a read only pass through the code to be refactored and write a record to CSPFIELDS for each data area definition or field definition that we find in the calculation specification. This information will be used to move the field and data area definitions out of the calculation specifications and into the definition specifications. Moving the fields up to the definition specifications is an always-on feature of the REFACTOR command, so it is not controlled by a parameter. In the next installment, this information will be expanded to include fields from all referenced files and it will be used for replacing MOVEs and arithmetic opcodes with EVAL's.
Admittedly, at this point, the REFACTOR tool is a bit sparse. However, each of the next three installments will add to it until it is able to accomplish much. The remainder of what you will need is in Figure 7 .
In closing the first installment, let me say this. The cataclysm for us programmers is not an asteroid, but the continual arrival of newer technologies. If we are to be like the mammals, and not the dinosaurs, we will need to continually adapt to the changing landscape ahead. Code refactoring is a well established software engineering tool that can assist us in keeping up with those changes. You would do well to embrace it. Now go forth my furry little friend, you have survived another article. Until next time!