How and why to convert subroutines to subprocedures
Last month, we wrote about why we write subprocedures instead of subroutines, and we promised to cover the basic “how to” this month. We'll use the same example (i.e., a subroutine that takes a date and calculates the day of the week for that date) and convert the code to a subprocedure, which gives us the chance to not only show the syntax changes needed, but also illustrate the benefits in more detail.
Here's the original subroutine code. We're not showing the entire program here—only the parts specifically relevant to the subroutine and one instance of calling it.
// Variables used by DayOfWeek subroutine
D WorkNum S 7 0
D WorkDay S 1S 0
D AnySunday C D'2009-08-02'
D WorkDate S D DatFmt(*ISO)
WorkDate = InputDate;
DayNumber = WorkDay;
//... Additional program logic omitted ...
// Calculate day of week (Monday = 1, Tuesday = 2, etc.)
WorkNum = %Diff( WorkDate : AnySunday: *D );
WorkDay = %Rem( WorkNum : 7 );
If WorkDay < 1;
WorkDay = WorkDay + 7;
Initially, we're going to simply convert this subroutine into an internal subprocedure. Later, as we mentioned last month, we could choose to externalize that subprocedure to be able to access it from multiple programs. But in this article, we'll just concentrate on the first step.
First, we may need to move the code for the subroutine within the source member. Subprocedures go after all of the ordinary main program logic. Subprocedures go after any O specs the member may contain but before any compile-time data.
The next step is to replace the BEGSR and ENDSR operations with P specifications. The P spec contains the name of the subprocedure (aka procedure) and either a B for begin or E for end. The procedure name is optional on the ending P spec, but it's a good idea to code it there for clarity when scrolling through the code. So our beginning and ending P specs will look like this:
P DayOfWeek B
P DayOfWeek E
A subprocedure can be thought of as a cross between a subroutine and a program. Like a subroutine, it can be (but doesn't have to be) coded in the same source member as the code that calls or runs it. However, it's more like a program in the sense that it accepts parameters and has its own local data definitions.
Search our new 2013 Buyer's Guide.
E-Newsletter | Namespace support makes the opcode a viable option
E-Newsletter | The finer points of OpenRPGUI, Part 1