You are currently on IBM Systems Media’s archival website. Click here to view our new website.

IBM i > DEVELOPER > RPG

Modules, Subprocedures and Files


RPG has changed a lot over the years. Long ago, no matter where we defined data—files, variables, arrays or structures—the data was available to all the code in the source member. Then along came subprocedures that allowed us to segregate our logic better by letting us have local data definitions. But for a long time, local data in subprocedures was limited to D specs—files were still global to the module. In Version 6.1, local data in subprocedures became complete. We can now have F specs in our subprocedures, making files local as well.

This increased the number of options available to us for how we use files in RPG. And one thing is certain—the more options we have, the more room for confusion there can be. We find there’s a lot of confusion relating to what does and does not happen automatically with the opening and closing of files in these situations. So we thought we’d address those questions.

In the early days, RPG did many things automatically for programmers, including opening and closing of files. The open happened automatically as part of the initialization of the program on the first call and the close was controlled by the LR indicator—*On and the files were closed when the program ended, *Off and the files were left open, ready for action on subsequent calls. Later programmers were given the capability to control the open behavior themselves with the user-controlled open (the USROPN keyword).

What happens now? Are files still opened automatically? The answer is yes; unless USROPN is specified, files are still opened automatically, whether local or global.

What about automatic closing of files? What role does the LR indicator play in closing files? The answer is—all together now—“it depends.” It depends first on whether the file is local or global in the module. And there are other dependencies in each case as well, so let’s look at the details in each scenario.

Local Files

Let’s first address the situation of local files in subprocedures. If you code an F spec after a P spec, then that file is local to the subprocedure. You can read more about local files in our article, “Major Changes in RPG File Handling.”

By default, a local F spec file will automatically be opened every time the procedure is called and it will be automatically closed every time the procedure ends (i.e., returns to its caller) regardless of the value of the LR indicator.

An important detail to note is that the LR indicator has no effect. LR is part of the RPG cycle and the RPG cycle doesn’t apply to subprocedures. In a way, it seems that subprocedures are behaving as if LR is always on, but it really has nothing to do with the cycle. Instead it has to do with automatic vs. static storage. Just like local D-spec-defined data in subprocedures, local files use automatic storage and therefore, the file’s storage disappears when the procedure returns to its caller. To understand more about static vs. automatic storage in subprocedures, read “Data Storage Options in Subprocedures.” That article was written before we had local files, but the principles of static vs. automatic storage are the same.

Of course, it may have occurred to you that there could be a potential negative performance impact in opening and closing the files on every call to the subprocedure. Is there something we can do to alleviate that?

Yes. Just as you can code the STATIC keyword on D-spec-defined data to keep it around between calls, you can use the STATIC keyword on your local files as well. That means the file will remain open at its current position and state between calls to the procedure.

So when will the local STATIC file be closed? Only when explicitly closed via a CLOSE operation or when the activation group ends. As we said earlier, the status of LR has no impact on closing a local file in a procedure, whether it uses static or automatic storage. This catches many RPGers by surprise when they find files remaining open long after the part of the application using them is finished.

Global Files

What about F specs that are global (i.e., those that appear before the first P spec in a module)? When are they closed?

This answer again is “it depends.” In this case, it depends on whether the module where the global F spec is coded contains the RPG cycle or not.

Remember that LR is part of the cycle, so if cycle code is present in the module, the LR indicator controls the implicit closing of the global files—just as it was in traditional RPG programs without subprocedures. But if the module has no RPG cycle code, then just as was true with the local files, LR had no impact on whether the files are closed.

So, how do you know whether your module contains RPG cycle code? Including RPG cycle logic is the default when compiling a module. Look at the H spec. If there is neither a MAIN nor a NOMAIN keyword (or, of course, if there’s no H spec) then the module will include the cycle logic.

The NOMAIN keyword has been with us for a while. It’s for modules that contain only subprocedures (no logic before the first P spec). We typically use it for modules destined to become part of a service program, although it could be bound by copy to a module that has main logic in it. But a NOMAIN module cannot be a program entry procedure module so it can never be the only module in a *PGM object.

The MAIN keyword was new as of V6.1. This allows RPGers to write all their logic as subprocedures and then specify one of the subprocedures to be the main controlling procedure in the module, such as MAIN(MyProcName). This type of module also has no RPG cycle logic (because it’s made up of only subprocedures); however, it can be a program entry procedure module and it could be the only module in a *PGM object.

So when it comes to global files in modules—in those modules that contain the RPG cycle (i.e., neither MAIN nor NOMAIN appears on the H spec)—the LR indicator will control when the files will be automatically closed. Conversely, if your H spec contains either MAIN or NOMAIN, then it has no RPG cycle code in it and therefore the LR indicator is ignored. We recommend that you code your own CLOSE operations for files used in modules with no cycle. Otherwise you’ll have to wait for the activation group to end to close the files and release the locks.

Closing Thoughts

We’ve addressed only the automatic opening and closing of files in this article. There are other differences in behavior between modules with and without the RPG cycle (e.g., things related to data areas). The RPG Reference manual has a good detailed look at more of these issues; take a look in Chapter 3, the sections entitled “Program Flow in RPG Modules: Cycle versus Linear” and “RPG Cycle and other Implicit Logic.” We normally access the RPG manuals from within Rational Developer, but if you use the Information Center, you can find the PDF here.

Jon Paris is a technical editor with IBM Systems Magazine and co-owner of Partner400.

Susan Gantner is a technical editor with IBM Systems Magazine and co-owner of Partner400.



Advertisement

Advertisement

2019 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.

New and Improved XML-INTO

Namespace support makes the opcode a viable option

Authenticating on the Web

The finer points of OpenRPGUI, Part 1

The Microphone is Open

Add your voice: Should IBM i include open-source RPG tools?

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
IBMi News Sign Up Today! Past News Letters