Writing a Subprocedure
Monday, June 2nd, 2008Late last week I prepared to write a subprocedure for a program I am currently working on. This was significant because, though subprocedures are recommended as a highly significant new way of modularizing our programming (subdividing the programs into manageable procedures rather than the monolithic program model of standard RPG), I had never written one myself, though I had maintained a few. Modularization is common to almost all modern computer languages except RPG. That is, until several years ago when subprocedures were added to RPGIV.
I had taken an introductory course in ILE RPG several years ago and learned about using subprocedures; but since that time, I had neither opportunity or (I confess) inclination to use them. I could see no burning reason to use them, for reasons I shall explain later.
But in this particular case, it seemed an opportune time to try it. The subprocedure would be based upon another program already written by someone else. Without going too deeply into the details, the program determined the status of a particular spooled file; on the basis of this determination, the program performed some other tasks and updated some files. I wanted to use the front portion of this program and use the status determined for another purpose and not update those files. To that end, I cloned the program, performed an amputation on the clone; with that and a little bit of plastic surgery, I had the processing in place that I wanted.
Most of the subprocedures that I had read about did not do any file processing; they were straight calculations. This program used several files, but I did not foresee that as a problem, since I understood that files could be part of subprocedures. I had done my research, and I had printed out what I considered a fine tutorial by Jon Paris that I had found on the Internet.
In line with some of the recommendations, I intended to use this as a separate module that would eventually be pulled together with my original program that would use my new module. I put NOMAIN in the Header specification to indicate that this new module was not a callable program by itself and would not use the RPG cycle. The process I was intending to implement needed to run as efficiently as possible, and the module would not need the cycle anyway.
So with high expectations I began to put together my sub-procedure. The tutorial mentioned above shows quite nicely how to do it, so I will not belabor the general process here. I fully expected to have some problems; you have to expect that sort of thing when you’re trying something for the first time.
So, how did it go?
As expected, I had all sorts of problems, mostly centered around where to put the Input specifications in the subprocedure. Finally, this morning, I figured out what I was doing wrong. I got the subprocedure module to compile, and I am now testing the main program. I seem to be getting more than satisfactory performance, which is what I was aiming for, along with some practice of how it was done.
However, while some think that subprocedures in RPG programs are the greatest thing since sliced bread, I simply don’t agree. Even those who like them admit that creating and using a subprocedure is more of a song-and-dance than a dynamic program CALL is. I had to compile the calling portion as a module, the subprocedure as a module, then run CRTPGM to link the two together. Additional code is also needed, in the form of prototypes and prototype interface definitions. I think a number of different factors might determine whether to use subroutines, dynamic CALLs, or prototyped CALLPs or prototyped function-like expressions. The “modern” way to do it may not necessarily be the best way.
I intend to discuss subprocedures in more depth in another post, as well as that hallmark of “modern” RPG, freeform RPG. In the meantime, back at the office, I will make the program work tomorrow.