29
Fri, Nov
0 New Articles

Improving Your Passing Game

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

The need to pass data between programs is as old as programming itself. Whether you are writing a series of interactive programs to enter data or writing a string of programs designed to run a report in batch, you will probably need to pass data between the various components.

There are so many ways to accomplish this that we found there was no way to fit them all into this article. Therefore, we decided to document a few of the methods we felt might not be as widely known.

Pushing the Rock Down the Field

Parameters are the most common way to pass data between programs and work particularly well when you are dealing with a limited number of data elements. However, they can be a pain from a maintenance standpoint. If the number of parameters or the definition of a parameter to be passed needs to be changed, all programs sharing those parameters need to be changed, too. This is a real headache if you have a large number of programs involved.

Our best advice is to employ a method for standardizing your parameters, and we will show you a couple of ways to do this. First, though, we’ll talk about a few shortcuts you can use to make dealing with parameters much easier.

The first shortcut involves using either the %PARMS built-in function or the *PARMS keyword in the program information data structure to control parameter usage. If you need to add a parameter to a program that is called by many other programs, this technique can come in handy.

Under normal circumstances, if you add a parameter to program A and do not add the same parameter to the programs that may call program A, your change will result in a series of runtime errors. But if you code program A to use the %PARMS built-in function, as shown in Figure 1, you will only need to change the calling program that necessitated the change. Other programs calling program A will not pass the new parameter, and the operating system will not care. Program A has been coded to use the new parameter only when it is passed. This method works well, but we consider it more of a quick fix. This code can get messy if you do many changes later on. Adding parameters can be a little more difficult when the variable number of parameters is used.

Our second and preferred shortcut is to use externally described data structures to describe parameters. An externally described data structure is really nothing more than a


physical file used to describe the data you want to pass. Many of the attributes that make an externally described data file such a powerful tool on the AS/400 also apply to an externally described data structure, because an externally defined data structure is really nothing more than a physical file without the data. Actually, a physical file with data could be used as an externally described data structure too, but that is a whole other story.

Because externally described data structures are defined in a single place, there is consistency in definition. Programs using the data structure are easier to maintain because they do not need to be modified when the data structure changes, unless the program happens to use the fields within the data structure that was changed.

If an externally described data structure does change, programs using that data structure need only to be recompiled, with two notable exceptions. The first exception is if the program uses one or more of the fields in the data structure that was changed, as we just explained. The second exception is if new fields were added to the end of the data structure. In this case, only the programs using the newly added fields need to be modified or compiled.

Figure 2 is an example of using an externally described data structure as a program parameter list. The code for the data structure, DATADEF, is seen in Figure 3. Any changes to the parameter list in Figure 2 would involve changing only the DDS seen in Figure 3 and then compiling it, just as you would any other physical file. Any program using the DATADEF data structure as a parameter list would need to be recompiled, but that is relatively easy.

Externally described data structures may also be used to define local data areas, data areas, and program-described files. We have found them extremely useful when passing data between programs.

Not Your Prototypical Passer

You thought we were done discussing parameters, didn’t you? Nope! As we have discussed, parameter passing is the most common method of exchanging data between programs. We want to show you yet another way to standardize your parameters. This method is called prototyping parameters.

The RPG IV language has built-in data integrity checking to ensure that the definition of the parameter data being passed is the same in both programs. So if program A defines a parameter as a 3-byte zoned decimal field and passes this parameter to program B, program B must be defined with the same parameter as a 3-byte zoned decimal field; otherwise, the system will alert you. Unfortunately, this data integrity checking occurs at runtime, and the system alerts you (usually through an irate user) with a very nasty, cryptic error message.

If you prototype the parameters, data integrity checking will be done at compile time instead of at runtime. This means that you, the programmer, will be alerted to the error, because your program won’t compile! This is a much better scenario than that of a raving lunatic (user) shouting at you about your programming skills—or lack thereof.

Prototyping can replace the CALL/PARM interface, even on existing programs. You do not have to change programs into procedures to use prototyping. Figure 4 shows an example of using the prototyped call interface to call an RPG program. Note the keyword EXTPGM on the prototype definition. This keyword tells the system to use an external program call to program EXISTS, making it the equivalent of using the CALL/PARM technique. The prototype defines the characteristics of the parameters being passed, not the names. In this example, there are three parameters being passed, each 10 bytes long. Although we have named each parameter in the prototype definition, we did so for documentation purposes only. The names are optional.

If you use the keyword EXTPROC or don’t specify a keyword on the prototype definition statement, the system will issue a procedure call. Prototyping procedures opens up many possibilities in the way parameters are defined.


The default method of passing data with parameters is to pass by reference. This means that, although you specify a field name as a parameter in your program, the system actually passes a pointer to the data, not the data itself. Using prototyped procedures allows you to pass data by value. This means that a copy of the actual data is passed, not a pointer to the data. Some APIs require this ability, as do some UNIX and C programs. There are far too many keywords that control the passing of parameters to cover in this short article. But, to whet your appetite, you can use the OPTION(*OMIT) keyword to cause a parameter to be ignored and subsequent parameters could still be specified.

Prototyping parameters requires that you include the prototype definition statement in the calling program. If you have more than one program that could call the same program, you would have to duplicate the prototype statement in every calling program. The best way to do this is by using the /COPY statement to put the prototype definition in the calling programs, thus ensuring consistency across programs.

Utilizing a User Space to Go Deep

If you have a tremendous amount of data to pass between programs, you might consider using a user space. A user space is simply an allocated area on disk set aside for later use. It has its own object type (*USRSPC) and can hold up to 16 megabytes of data. This should be more than enough space for most applications in which you need to pass data between components.

You can think of a user space as one large data area, but there are some key differences. First of all, there are no IBM-supplied commands to create, display, or change a user space. Access to the data in a user space is accomplished via APIs—the Retrieve User Space API (QUSRTVUS) or the Retrieve Pointer to User Space API (QUSPTRUS). You can use another special data type called a pointer to get at the data, but you must use an API to get the pointer. From a security standpoint, this lack of command interface provides some superficial measure of protection in that the average user cannot see the data in the space.

To pass data between programs using a user space, as shown in Figure 5 (page
99), one program would put data in the space and another program could use it as needed. The two programs could agree ahead of time on the name of the user space, in which case no parameters would need to be passed between them. If you need more flexibility, you could have one program create a space and pass the name and library (or a pointer) to another program.

In Figure 5, the program PASSUSRSP1 calls the program PASSUSRSP2. This program creates a user space and then loads a multiple occurrence data structure into it. It also loads the number of occurrences that it used into a 4-byte field called NbrOfOccurs.

The program PASSUSRSP1 gains access to the user space by using the Retrieve Pointer to User Space API (QUSRTVUS) to get a pointer to it. Since we have based the NbrOfOccurs field on the same pointer returned by this API, we have filled the value of NbrOfOccurs with the first 4 bytes of the user space. Since the first 4 bytes of the user space contain the number of occurrences of the multiple occurring data structure used in PASSUSRSP2, we have essentially passed this information between the two programs.

The PASSUSRSP1 program is able to get to the data in the multiple-occurring data structure (loaded in program PASSUSRSP2) by simply basing its definition on a pointer. The pointer used is the same one pointing to the user space, plus the 4 bytes used by the NbrOfOccurs field.

We should point out that you could simply have passed the multiple-occurrence data structure and the number of occurrences used as parameters on the call to PASSUSRSP2. But using the user space allows you to keep the data around after the programs end. It also allows programs that don’t call each other directly to pass data. For instance, an interactive program might use a user space to pass data to a batch program. Consider this method another play in your playbook.


Export/Import: The Forward Pass

This method has nothing to do with trading goods with overseas partners. Instead, it is yet another method for trading information between programs. EXPORT and its counterpart IMPORT are keywords in the definition specification of a variable field (or data structure) within a module. The EXPORT keyword indicates that the value in the field can be retrieved by another module in the program by using the IMPORT keyword. The IMPORT keyword indicates that you are retrieving the value from another module.

There are some restrictions on using this technique. One of those restrictions is that only one module may define the data as exported. For example, you cannot export a field that is also specified as a parameter on an *Entry Plist. Another restriction is that you cannot export an unnamed data structure or data items that use the BASED keyword.

Figures 6, 7, and 8 show this technique in action. Figure 6 shows a program using two bound modules named EXPORTEXMP and IMPORTEXMP. The EXPORTEXMP module is shown in Figure 7. Note the keyword EXPORT on the definition of the data structure PassData. This keyword makes the data structure available for another module to import it. Figure 8 illustrates a module doing exactly that. It has the data structure defined with the IMPORT keyword. When the code in the IMPORTEXMP module is executed, the data structure already contains the information put there by the EXPORTEXMP module. It is a completed forward pass.

Just because you now know how to use the EXPORT and IMPORT keywords to pass data from one program to another doesn’t mean you should. The use of this technique should be severely limited. If you look up the EXPORT keyword in the manual, you’ll see this tip:

The keywords IMPORT and EXPORT allow you to define a “hidden” interface between modules. As a result, use of these keywords should be limited only to those data items which are global throughout the application. It is also suggested that this global data be limited to things like global attributes which are set once and never modified elsewhere.

The keyword in that quote is “hidden.” Unless you are aware of the technique, it is very difficult to tell that data is being passed from one program to another. Even worse, it’s difficult to tell what modules are passing the data! As a programmer, you need to be aware of this technique, but you should avoid using it.

Pass Me a Beer, Please

Moving data from one program to the next is a necessary task. But you can make your life a little easier if you think ahead. We have given you several examples of how you can be proactive in the way you code your programs. A few extra minutes on the front-end may save you a lot of time when you are maintaining the code later on. Now back to the game...

C *ENTRY PLIST
C PARM Parm1
C PARM Parm2
C PARM Parm3

C If %Parms > 2

* Do whatever you want with Parm3...
C EndIf D ParmDtaStr E DS EXTNAME(DATADEF)
C *ENTRY PLIST


Figure 1: Use the %Parms built-in function to control a variable number of parameters.

C PARM ParmDtaStr D ParmDtaStr E DS EXTNAME(DATADEF)
C *ENTRY PLIST
C PARM ParmDtaStr
Figure 2: You can use an externally described data structure to pass parameters.

A R DATADEF
A DEVICE 10A COLHDG('Tape Device')
A PRINTER 10A COLHDG('Printer Name')
A OUTQUEUE 10A COLHDG('OutQueue')

D Exists PR ExtPgm('Exists')
D Object 10 const
D Objecttype 10 const
D ObjectLib 10 const options(*nopass)

D Object S 10
D ObjectType S 10
D ObjectLib S 10

* Call the program using prototyped call
C CALLP EXISTS(object:objecttype:objectlib)

* Call program using CALL/PARMS
C CALL 'EXISTS'
C PARM Object
C PARM ObjectType
C PARM ObjectLib D Index S 4 0
D NbrOfOccurs S 4 0 based(SpacePtr)
D UserSpace S 20 inz('SPACENAME QTEMP')

D MultOcurDs DS Occurs(2) based(OccurPtr)
D Field1 5
D Field2 3 0

* Create user space and populate it with MODS
C CALL 'PASSUSRSP2'

* Get pointer to user space
C CALL 'QUSPTRUS'
C PARM UserSpace
C PARM SpacePtr

* First 4 postions has number of occurances, followed by multiple

* occuring data structure
C Eval OccurPtr = SpacePtr + 4
C Do NbrOfOccurs Index
C Index Occur MultOcurDs
C field1 dsply
C EndDo

C eval *inlr = *on c callb 'EXPORTEXMP'
c callb 'IMPORTEXMP'
c eval *inlr = *on

Figure 6: Two modules use the EXPORT and IMPORT keywords to share data.


Figure 2: You can use an externally described data structure to pass parameters.

Figure 3: This physical file does not contain data and exists only to define an externally described data structure.

Figure 4: Prototyping calls to programs enables type-matching at compile time.

Figure 5: User spaces are a powerful way to pass data from one program to another.

d PassData DS export
d Field1 6 0
d Field2 9

c Time Field1
c Eval Field2 = 'Something'
c eval *inlr = *on d PassData DS import
d Field1 6 0
d Field2 9

c field1 dsply
c field2 dsply
c eval *inlr = *on

Figure 7: The EXPORT keyword indicates data that is available for use in another module.

Figure 8: The IMPORT keyword indicates data that is part of another module.


BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: