![The AS/400 Programmer's Handbook, Volume II: More Toolbox Examples for Every AS/400 Programmer](http://vs-images.bn-web.com/static/redesign/srcs/images/grey-box.png?v11.12.2_temp1)
The AS/400 Programmer's Handbook, Volume II: More Toolbox Examples for Every AS/400 Programmer
394![The AS/400 Programmer's Handbook, Volume II: More Toolbox Examples for Every AS/400 Programmer](http://vs-images.bn-web.com/static/redesign/srcs/images/grey-box.png?v11.12.2_temp1)
The AS/400 Programmer's Handbook, Volume II: More Toolbox Examples for Every AS/400 Programmer
394eBook
Available on Compatible NOOK devices, the free NOOK App and in My Digital Library.
Related collections and offers
Overview
Product Details
ISBN-13: | 9781583474921 |
---|---|
Publisher: | MC Press, LLC |
Publication date: | 02/22/2016 |
Sold by: | Barnes & Noble |
Format: | eBook |
Pages: | 394 |
File size: | 22 MB |
Note: | This product may take a few minutes to download. |
About the Author
Read an Excerpt
The AS/400 Programmer's Handbook, Volume II
More Toolbox Examples for Every AS/400 Programmer
By Mark McCall
Midrange Computing
Copyright © 2000 Midrange ComputingAll rights reserved.
ISBN: 978-1-58347-492-1
CHAPTER 1
Modular Coding Techniques
In programming, much of what is done is redundant, a fact that seasoned programmers who have been in the trenches for many years are well aware of. By the time a programmer has been on the job for more than a couple of years, he or she probably does more copying and adapting of code that already exists than writing new code from scratch. It is simply more efficient to leverage work that has already been done than to start from scratch every time. This technique of reusing and reapplying work that has already been done can lead to tremendous gains in productivity.
Another major benefit of reusing software components is reliability. Modular components are easier to test more thoroughly than full applications. Once tested and verified to work correctly, a component can be reused without being fully retested.
When thinking about designing code that can be used and reused throughout an application, one must maintain a balance between achieving modularity and maintaining acceptable performance levels.
Common Modular RPG Coding Techniques
The introduction of the Integrated Language Environment (ILE) for RPG empowered the language with the tools necessary for building reusable component-based software. ILE allows you to call on services from external providers without suffering from the poor performance that plagues dynamic program calls. Prior to ILE, the ability to build component-based software relied strictly on dynamic program calls or methods of sharing source code.
This chapter presents examples based on a variety of modular or component-based design techniques. The following is a list of today's most commonly used techniques to reuse software in RPG on the AS/400:
* /Copy compiler directives
* Internal subroutines
* External subprograms
* ILE subprocedures
* ILE service programs
* * *
Example
Using the /COPY Compiler Directive
This example employs the /COPY compiler directive to copy source code from a central repository, often called a copybook, into a desired program. This technique of reusing source code is one of the oldest available to AS/400 programmers. While this technique has become outdated for many applications, copybooks remain an effective tool for storing ILE Procedure Interface definitions. The example takes a common generic programming task, determining the day of week for a given date, and deposits the code into a copybook, where it can be used by multiple programmers in multiple programs.
What the Example Does
The example consists of three source members. Members MOD002R and MOD003R contain copybook source that determines the day of week for a given date. Member MOD001R employs the copybooks using the /COPY directive. The mainline program logic in MOD001R accepts a date as an input parameter, then uses the copied source to determine the date's day of week. The resulting day is displayed for viewing. Listing 1.1 shows the mainline program MOD001R, while Listings 1.2 and 1.3 show the copybook source members.
How the Example Works
RPG provides a number of directives that perform specific functions when the program source compiles. As its name implies, the /COPY compiler directive allows you to instruct the RPG compiler to copy in source member records from a different member before compilation.
When creating source copybooks, you can isolate a generic segment of code into a source member. Because the member is usually just a snippet of code, or a specific generic function, copybook source is never compiled. It is simply a repository for common routines that are copied and included in the compilation of other source members.
Source statements copied by the /COPY directive are placed into the target member at the point the /COPY appears. Because of this, it may be necessary to divide a single function into multiple copybooks. For instance, the example code that determines the day of week for a given date consists of two parts: definition specs for the used fields and the calculation specs that do the actual work. These two portions of the code are divided into two individual source members. The code is divided because the definition specs need to be copied into the definition specs of the target source, while the calculations may be copied one or more times into various locations within the target member. It is important to remember that source copied into one member from another must still conform to the basic structure and sequencing requirements of RPG in order to compile.
The syntax of the /COPY directive can be explicit or implied. That is, you can provide a fully qualified library, source file and member name, a source file name and member name, or simply a member name. If a library is not specified, the library list of the compiling job is used. If a source file name is not specified, the system assumes the file to be QRPGLESRC. A member name must be specified.
Source members MOD002R and MOD003R are never compiled as standalone modules. When either the Create RPG Module (CRTPRGMOD) or Create Bound RPG Program (CRTBNDRPG) commands are used to compile the member MOD001R, the copybook members are integrated into the source prior to the actual compile.
The example employs two system APIs to derive the day of week. For detailed information about the use of these APIs, please refer to chapter 4.
* * *
Example
Using Internal Subroutines
This example employs an internal subroutine to share code within a single module. Subroutines are grouped segments of code, usually performing a very specific function that can be executed from multiple points in a module. As a general rule, subroutines deliver the best performance of all modular-coding techniques. The primary weakness of the subroutine is its inability to export its services across modules or procedures. The example takes a common generic programming task, determining the day of week for a given date, and deposits the code into a subroutine where it can be executed multiple times within the same module.
What the Example Does
The example presents member MOD004R that uses an internal subroutine coding technique to determine the day of week for a given date. MOD004R accepts a date as an input parameter, then uses the subroutine to determine the date's day of week. The resulting day is displayed for viewing. Listing 1.4 shows the source member MOD004R.
How the Example Works
RPG subroutines are routines that can be executed from any point within a procedure's calculation specifications. Subroutines are coded after the main body of code in the calculation's specs. They are defined using a unique subroutine name coded with the Begin Subroutine (BEGSR) op code. The end of the subroutine is identified using an End Subroutine (ENDSR) op code. They are executed using either the Execute Subroutine (EXSR) or Case (CASxx) op codes. When executed, program control branches from the executing line of code to the first line of code in the subroutine. The subroutine code executes until the end of the subroutine is encountered or until a GOTO or Leave Subroutine (LEAVESR) operation is performed. Upon completion of the subroutine, control is returned to the line of code that executed it.
The RPG Subroutine
A subroutine cannot contain another subroutine, but it can execute another subroutine. A subroutine cannot execute itself recursively.
It is important to understand that subroutines share all the variables and memory space with the rest of the module. A field defined within the subroutine can be accessed and altered outside the subroutine. In addition, fields defined outside the subroutine can be accessed and altered within the subroutine. The subroutine is merely a technique used to organize source code to reduce redundancy.
The example presented employs two system APIs to derive the day of week. For detailed information about the use of these APIs, please refer to chapter 4.
* * *
Example
Using Dynamic Subprograms
This example employs a dynamic call to an external subprogram to access a shared function from an external provider. Subprograms are isolated routines that perform a very specific function that can be called from multiple modules or programs. Subprograms called dynamically, that is those that are not bound to the program object at compile time, carry significant overhead. Because they are called dynamically, the location of the program is not resolved until the call is performed.
The user library list is searched until the called program object is located. It can then be loaded into memory and executed. As a general rule, subprograms called dynamically deliver poor performance relative to newer techniques employing ILE early binding. The advantage delivered by dynamic calls is their simplicity. Because the object is not resolved until run time, internal changes made to the subprogram object immediately impact the programs that call it without recompilation.
The example takes a common generic programming task, determining the day of week for a given date, and deposits the code into a subprogram where it can be executed multiple times from any module or program.
What the Example Does
The example consists of two source members. Member MOD006R contains source that determines the day of week for a given date. It accepts the date as an input parameter and returns the day of week as an output parameter. Member MOD005R calls the subprogram dynamically using the CALL op code. The mainline program logic in MOD005R accepts a date as an input parameter, then calls the program MOD006R to determine the date's day of week. The resulting day is displayed for viewing. Listing 1.5 shows the mainline program MOD005R, while Listing 1.6 shows the subprogram.
How the Example Works
Prior to the introduction of ILE, there was only one way to dynamically call one program from another. Today, RPG provides three ways to call one program or module from another, including:
* Dynamically
* Bound by copy (static or early binding)
* Bound by reference (late binding)
Dynamic Program Calls
Programs called dynamically are coded using the RPG CALL op code. All resolution of the program object are performed when the CALL executes. Details such as the number and type of parameters being passed are not checked until the program is called. The program being called does not even have to exist when the calling program is compiled. This adds significant overhead to each CALL operation. If you need to call non-ILE programs, they must be called dynamically.
Bound by Copy Calls
Modules bound by copy are coded using the RPG CALLB op code. Binding by copy simply means that two or more RPG modules are combined into a single program object by the Create Program (CRTPGM) command. All resolution of module details such as the number and type of parameters being passed are checked when the program is created. To create the program object, all the modules being bound together must exist in the programmer's library list. Binding by copy delivers the best performance of all calling options.
Bound by Reference Calls
Calls to modules bound by reference are coded using the RPG CALLP op code or an exported procedure name in an EVAL statement. Procedures to be called are combined into a special type of program object called a service program. Binding by reference simply means that one or more RPG modules are combined into a single program object with a reference to a service program by the CRTPGM command. All resolution of details such as the number and type of parameters being passed are checked when the program is created. Most of the overhead associated with the procedure call is experienced when the program activation occurs. Subsequent calls do not experience the overhead, as with dynamic calls.
The ILE RPG Example Program
The example program calls a second program, MOD006R, dynamically. If the program will be called repetitively, changing the CALL op code to a CALLB op code and binding by copy will significantly improve call performance.
When the CALL operation is encountered, program control switches to the program being called. The subprogram code executes until the Return op code ends execution. Upon completion of the subprogram, control is returned to the line of code that called it.
A subprogram called dynamically maintain unique variables and memory space from the program that called it. The only field values shared between programs are those passed as parameters. The example subprogram presented employs two system APIs to derive the day of week. For detailed information about the use of these APIs, refer to chapter 4.
* * *
Example
Using ILE Subprocedures
This example demonstrates a call to an internal subprocedure to share code within a single module. Similar to subroutines, subprocedures are isolated segments of code, usually performing a very specific function that can be executed from multiple points in a module. The primary weakness of the internal subroutine is its inability to export its services across modules. ILE subprocedures can be exported, allowing them to be accessed outside the module in which they reside. The example takes a common generic programming task, determining the day of week for a given date, and deposits the code into a subprocedure where it can be executed multiple times within the same module.
What the Example Does
The example presents member MOD007R that uses an ILE subprocedure coding technique to determine the day of week for a given date. MOD007R accepts a date as an input parameter, then uses the subprocedure to determine the date's day of week. The resulting day is displayed for viewing. Listing 1.7 shows the source member MOD007R.
How the Example Works
Before delving into the example implementation of an ILE subprocedure, it is important to understand a few basic ILE terms and concepts.
Programs, Modules, Procedures, and Subprocedures
If you are new to the concept of ILE development, it is vitally important to understand the basic building blocks of an ILE application. Prior to ILE RPG, application development consisted of source members that were compiled to make a program. The concept of what a program is differs in an ILE application. Modules, procedures, and subprocedures are new concepts to RPG.
The ILE Program
Before ILE, the RPG code statements residing in a source member equated to an RPG program. In ILE, there no longer is such a thing as an RPG program. Rather, a program is an executable object independent of the language or languages used to create it. An ILE program is an executable object comprised of one or more modules. When you create a program, you specify the name of the module that contains the program entry procedure. This specifies which module is to be called first when the program is activated.
The ILE Module
The RPG code statements residing in a source member equate to an ILE module. A module is not an executable object — you cannot run a module. Rather, it is an important component of an ILE program. A module can consist of one or more procedures and data specifications. A module extends its capabilities through an ability to export and/or import data or procedures for use by other ILE objects.
The ILE Procedure
A procedure is simply a collection of RPG code statements that perform a specific function. There are two types of procedures: main procedures and subprocedures. A main procedure is the section of a module that can be used as an entry procedure. It is simply the main body of the module and can include H, F, D, I, C, and O specs. A module can have no more than one main procedure.
A subprocedure is an isolated section of code within the module that is enclosed in procedure specifications. Multiple subprocedures can be coded after the main procedure section of the module. It is also possible to create a module that consists only of subprocedures and does not have a main procedure. In this situation, the subprocedures are accessible only by other ILE objects. It cannot be used as an entry procedure for a program. Modules created without a main procedure are unique. When compiled, the normal RPG cycle logic you are accustomed to is not included in the object. This is why a module without a main procedure cannot be used as a program entry procedure. A subprocedure can include only P, D, or C specifications.
Subprocedures are called either using CALLB or CALLP op codes or as expressions on op codes formatted like calls. Op codes that can be used to call subprocedures include EVAL, EVALR, IF, WHEN, DOU, DOW, and FOR.
Scoping of Fields
One of the greatest features of subprocedures is their capability to scope fields to the subprocedure level. This means that fields defined within the subprocedure are hidden to the code outside the subprocedure. The fields are not recognized and do not exist to other subprocedures or to the main procedure. The scoping is thus considered local only to the subprocedure. If you desire specific field definitions and values to become enabled to other procedures, they can be explicitly exported. This affords you a great deal of control over the operating environment.
(Continues...)
Excerpted from The AS/400 Programmer's Handbook, Volume II by Mark McCall. Copyright © 2000 Midrange Computing. Excerpted by permission of Midrange Computing.
All rights reserved. No part of this excerpt may be reproduced or reprinted without permission in writing from the publisher.
Excerpts are provided by Dial-A-Book Inc. solely for the personal use of visitors to this web site.
Table of Contents
Contents
INTRODUCTION,Part 1: RPG Programming Examples,
Chapter 1: Modular Coding Techniques,
Chapter 2: Built-In Functions,
Chapter 3: Exit Programs,
Chapter 4: Application Programming Interfaces,
Part 2: Database Examples,
Chapter 5: Database Constraints,
Chapter 6: Database Triggers,
Chapter 7: Using SQL,
Appendix: Software Loading Instructions,