This is the second article in a multipart series on the ILE RPG language planned for release later this year. In each article, we will cover specific changes to RPG coding and some of the broader design issues resulting from the new features and underlying ILE facilities.
IN THIS ARTICLE... The new Definition Specifications.
COMING NEXT MONTH... I-specs, C-specs and O-specs.
Brief: In the second installment of our indepth coverage of ILE RPG, we'll look at the new Definition Specifications (D-specs). D-specs consolidate definitions for arrays, data structures, named constants, data areas and work fields that are not part of any file. They replace E-specs and take over some functions from RPG/400, I-specs and C-specs. In addition, D-specs provide new ways to define some data constructs.
Last month, we introduced the new ILE (Integrated Language Environment) RPG which should be announced as part of V3R1M0. We saw that a lot of changes are in store for the RPG programmer. Field, file and other symbolic names can now be up to 10 characters long. Upper- and lowercase field names are now supported. Many limits have been increased and others virtually eliminated.
Control Specifications (H-specs) have been transformed from fixed format to keyword notation. Line Counter Specifications (L-specs) have been eliminated and their function moved to File Description Specifications (F-specs). And the F-specs themselves have undergone major changes, not just to accommodate longer file names and larger record and key lengths, but also due to the use of keyword notation for file continuation keywords and other file attributes.
We're about to see even more radical changes. Extension Specifications (E- specs) have been eliminated entirely. Array and table definitions have been moved to the new Definition Specifications (D-specs). Named constant and data structure definitions have been moved from Input Specifications (I-specs) to the D-specs. Definitions for LIKE fields and data areas are also supported in D-specs. 1 illustrates the overall design of a D-spec and where each entry is coded.
We're about to see even more radical changes. Extension Specifications (E- specs) have been eliminated entirely. Array and table definitions have been moved to the new Definition Specifications (D-specs). Named constant and data structure definitions have been moved from Input Specifications (I-specs) to the D-specs. Definitions for LIKE fields and data areas are also supported in D-specs. Figure 1 illustrates the overall design of a D-spec and where each entry is coded.
Let's take a look at D-specs and see how they can improve your productivity.
Definition Specifications (D-specs)
The D-specs are designed to consolidate all data definitions in one section of your program. Although you can still define fields in C-specs, your code will be easier to maintain if you define all your work fields and literals in D- specs.
You may hear some people refer to D-specs as Data Specifications. While D-specs do define data, the proper terminology is Definition Specific-ation so that's what we'll try to remember to use.
In the following sections, we'll begin by looking at simple data constructs such as named constants and work fields. Then, we'll look at more complex examples such as data structures and arrays. Both an RPG/400 and an ILE RPG solution are shown whenever possible. However, the explanation of each example concentrates on the ILE RPG implementation.
Named Constants
In RPG/400, named constants can appear anywhere in I-specs, even within a data structure definition. This is not true in ILE RPG. Named constants cannot appear within a data structure definition. If the RPG/400-to-ILE RPG source- conversion utility finds named constants embedded in a data structure, it moves the named constants outside of the data structure as part of the source- conversion process.
2 shows the definition of several named constants: the character constants CMPNY and LWR, the numeric constant TWENTY, and the hexadecimal constant DUP. Only a few entries are required:
Figure 2 shows the definition of several named constants: the character constants CMPNY and LWR, the numeric constant TWENTY, and the hexadecimal constant DUP. Only a few entries are required:
o The C in position 24 defines a named constant.
o The value you enter for the CONST keyword defines the value of the constant. Although a value is required for the constant, you do not have to preface the value with the CONST keyword.
The first constant, CMPNY, uses the CONST keyword to define a character string. The second example includes several variations:
o The CONST keyword is omitted and the character constant is defined by enclosing the literal value in single quotes.
o The trailing hyphen indicates that the value continues on the next line, starting with the first character of the functions section (position 44).
The final two examples show the definition of noncharacter constants. The numeric constant TWENTY is defined by specifying a numeric value not enclosed in single quotes. Hexadecimal constants can be defined by specifying an X followed by a valid hexadecimal value enclosed in single quotes. In the example, DUP is defined as a hexadecimal constant with a value of X'1C' to represent the character returned when the DUP key is pressed. The actual CONST keyword is optional for all constants, regardless of their data type.
Stand-alone Fields
Traditionally, RPG programmers have defined work fields in C-specs. Although this is still possible using ILE RPG, you can define stand-alone fields that are not part of any file or data structure in D-specs.
We'll look at several examples in 3. One special entry is required for stand-alone fields:
We'll look at several examples in Figure 3. One special entry is required for stand-alone fields:
o An S in column 24 of the D-spec defines a stand-alone field.
The first example is a seven-digit, work field (PACK72). It is stored in packed-decimal format and has two decimal places. In RPG/400 you are forced to make this field part of a data structure even though it does not logically need to be associated with any other field.
o The length of the field is coded in positions 33 to 39 rather than using starting and ending positions.
The positions within the D-specs are different than those for I-Specs but contain the same type of entries.
Our second example defines LRGROS based on the field PRGROS. LRGROS is defined as two characters larger than PRGROS. ILE RPG permits you to use either the LIKE keyword in D-specs or the *LIKE DEFINE operation in C-specs to define a field based on the characteristics of another field.
The final example of a stand-alone field illustrated in 3 defines XXNAME with the same characteristics as the field PRNAME. One new keyword is added for this example:
The final example of a stand-alone field illustrated in Figure 3 defines XXNAME with the same characteristics as the field PRNAME. One new keyword is added for this example:
o The INZ keyword specifies the value to which a field is initialized. Initializing fields using this method is more efficient than initializing them in the C-specs. When the INZ keyword is not specified, the default value is blank for character fields and zero for nu-meric fields.
Data Structures
Complex data organizations are one of the primary reasons for adding D-specs to the RPG language definition. The first of these more complex forms that we'll examine is the data structure.
4 illustrates two ways to code a data structure in ILE RPG. In the first example, the ILE RPG code is very similar to the RPG/400 code. It uses absolute notation to designate the starting and ending positions of each subfield. The differences between the RPG/400 example and this ILE RPG example are based on general rules for formating ILE RPG.
Figure 4 illustrates two ways to code a data structure in ILE RPG. In the first example, the ILE RPG code is very similar to the RPG/400 code. It uses absolute notation to designate the starting and ending positions of each subfield. The differences between the RPG/400 example and this ILE RPG example are based on general rules for formating ILE RPG.
o The subfields may be indented to make the data structure easier to understand.
o You can use lowercase or uppercase field names at your discretion. As we mentioned last month, lowercase field names will be automatically translated to uppercase by the compiler.
The second ILE RPG sample takes advantage of a several new features.
o Length notation is used instead of specifying the starting and ending positions for each field. The length of each subfield is specified in positions 33 to 39. The rest of the syntax is identical to absolute notation (e.g., coding a 'P' for packed data, specifying decimal positions, and so forth).
o The OVERLAY keyword further subdivides a subfield within a data structure. The first parameter indicates the name of the subfield whose storage is to be overlaid. This subfield must have been previously defined in the same data structure. The second parameter specifies the starting position within the field. The starting position is optional and defaults to 1.
As shown in this example, OVERLAY(GLNUM) is specified for the field glcmpy. Since glcmpy has a length of 2 and the starting position defaults to 1, the field glcmpy is defined as the first two positions of the field glnum. For the field glmain, we specified OVERLAY(GLNUM:3). Since glmain has a length of 4 and the starting position is 3, the field glmain is defined as positions 3 to 6 of the field glnum. Finally, the field glsub is defined as positions 7 to 11 of the field glmain.
When using the OVERLAY keyword, the subfield being defined may not extend beyond the end of the field being overlaid. In our sample, specifying OVERLAY(GLNUM:8) for the field glsub would cause an error. Because glsub is a five-character field, starting in position 8 would extend this field to position 12. Since glnum is only 11 characters in length, an error would occur.
If length notation is used, any changes to starting position within the field glnum will not affect subsequent fields that aren't part of glnum. Overlaid fields, however, will be affected. For example, if you increase the length of glnum to 13 and of glmain to 6, you should change the starting position of glsub so that glmain and glsub do not overlap. But no changes are required for the fields glclas and glcat.
Length notation can make future modifications easier than using absolute notation. When the length of a field changes, the subsequent fields do not have to be modified. In this example, the field gldesc could be expanded to 40 positions without making any changes to the definition of glnum or its subfields. Nice job, IBM!
5 illustrates an externally defined data structure. The ILE RPG portion of this example uses several keywords that were shown in previous examples or in last month's article on H-specs and F-specs. One new keyword is introduced.
Figure 5 illustrates an externally defined data structure. The ILE RPG portion of this example uses several keywords that were shown in previous examples or in last month's article on H-specs and F-specs. One new keyword is introduced.
o The E in column 22 specifies that this is an externally defined data structure.
o The EXTNAME keyword indicates that the data structure is defined based o the definition of the first (or only) record format of the file OELPMNM. To explicitly define the record to be used, you might code EXTNAME (OELPMNM:OELPMNM9), indicating the record format OELPMNM9 should be used even if it is not the first record format in the file.
o The PREFIX keyword implicitly renames the fields in the data structure. This global rename function is similar to what we covered in F-specs last month. PMFNUM is renamed P2_PMFNUM, PMTNUM is renamed P2_PMTNUM, PMFZIP is renamed P2_PMFZIP, and PMTZIP is renamed P2_PMTZIP.
o The INZ keyword was specified for the data structure DSSEL to initialize numeric subfields to zero and character subfields to blank. The INZ keyword on the subfield lines for P2_PMTNUM and P2_PMTZIP overrides the default initialization for the data structure DSSEL.
Finally, we have explicitly renamed the field PMFLAG to XXPMFLAG. The PREFIX keyword does not affect an explicitly renamed field; so there will be a field named XXPMFLAG in the program, but there will not be fields named P2_PMFLAG or PMFLAG unless they are defined elsewhere.
The example in 6 associates a data structure with an external data area. It uses one new keyword.
The example in Figure 6 associates a data structure with an external data area. It uses one new keyword.
o The U in position 23 indicates the data structure is a data area.
o The DTAARA keyword can be used to specify the name of a data area. Special parameter values for this keyword are *LDA for the local data area and *PDA for the PIP (program initialization parameters) data area.
ILE RPG permits you to use either the DTAARA keyword in D-specs or the *DTAARA DEFINE operation in C-specs to associate external data areas with internal program structures.
Tables and Arrays
In this section, we'll look at several examples of arrays and tables and the new capabilities that ILE RPG provides for them.
The essential definition of arrays has not changed. ILE RPG supports the three types of arrays (compile-time, prerun-time and run-time) currently available with RPG/400, and the same basic rules apply. However, ILE RPG uses keywords to define the number of elements, from and to files, and the type of array. As in RPG/400, an array becomes a table if its name begins with the letters TAB. We'll refer to tables and arrays generically as arrays unless an example specifically uses a table.
7 shows a run-time array coded in RPG/400 using an E-spec, and coded in ILE RPG using a D-spec. This example illustrates the new structure of array definitions.
Figure 7 shows a run-time array coded in RPG/400 using an E-spec, and coded in ILE RPG using a D-spec. This example illustrates the new structure of array definitions.
o The S in position 24 of the D-spec has the same meaning as it has for stand-alone fields. It indicates that the array is not part of a data structure.
o The length for each element is coded in positions 33 to 39.
o The DIM keyword defines the dimension (the number of elements) of the array.
8 shows a compile-time array. Several new keywords are required to define how the compile-time array data is included in the source code.
Figure 8 shows a compile-time array. Several new keywords are required to define how the compile-time array data is included in the source code.
o The CTDATA keyword indicates the array will be loaded from compile-time data included at the end of the source member.
o The PERRCD keyword is used for compile-time and prerun-time arrays to specify the number of elements loaded from each record. The default is PERRCD(1) when CTDATA is specified, so this parameter does not have to be coded. It is included here to make the code easier to understand.
o Finally, the ASCEND keyword signifies that the array is in ascending sequence. Use of the DESCEND keyword would designate descending sequence.
9 introduces several additional concepts. This example loads two tables (everything in this example is valid for arrays as well as tables) from a file at prerun-time. The data is loaded the first time the program is called. There are three new keywords:
Figure 9 introduces several additional concepts. This example loads two tables (everything in this example is valid for arrays as well as tables) from a file at prerun-time. The data is loaded the first time the program is called. There are three new keywords:
o The ALT keyword is specified to associate the alternating table TABTOT with the primary table TABDPT.
o FROMFILE(OLDDEPT) causes the tables TABDPT and TABTOT to be loaded from the file OLDDEPT when the program is called for the first time.
o The EXTFMT keyword can be used to specify the external data format for compile-time and prerun-time arrays. In this example, EXTFMT(P) specified for the table TABTOT indicates that data elements of this table are stored in packed, decimal format in the file OLDDEPT. Other formats, including the new date and timestamp formats, are also valid.
In this example, the PERRCD(1) keyword must be coded. PERRCD(1) specifies that one element of each table is loaded from each record of the file OLDDEPT.
The keywords for the table TABDPT continue on a second line. If positions 7 to 43 of a D-spec are blank, the compiler assumes the line is a continuation of the previous line. In fact, a keyword can be coded on one line and its parameter coded on the next line, as in the case of the keyword FROMFILE and its parameter OLDDEPT. However, you should not code in this manner since it can be confusing; the code is included here for illustration purposes only. ILE RPG also permits spaces between the keyword and its parameter, as shown with the PERRCD keyword.
10 shows the run-time array SRT. Because this is a run-time array, the PERRCD keyword is not used. There is one new keyword in this example:
Figure 10 shows the run-time array SRT. Because this is a run-time array, the PERRCD keyword is not used. There is one new keyword in this example:
o The INZ keyword permits different initialization values to be specified for the array. In the ILE RPG example, we have specified a default value of *HIVAL at compile time, instead of using a MOVE in C-specs at run time as you see in the RPG/400 sample.
The INZ keyword causes the array to be initialized with the specified value the first time the program is called. If the program returns without setting on LR and is called again, the INZ keyword has no effect the second time the program is called so the array still has the same value it had when the program last returned. By default, the initialization values are based on the data type- blanks for character data and zeroes for numeric data. To illustrate this point, the sample explicitly defines SRT as a character array with the data type of A in position 40. The data type is optional because, as in DDS, a field with no decimal positions specified defaults to a character field.
With the constraints of RPG/400 E-specs removed, what's in the future for arrays in ILE RPG? How about a two-dimensional array coded with a technique such as DIM(99:12)? In our sample, this might indicate 99 elements in the first dimension and 12 in the second. Perhaps we'll see this support in a future ILE RPG release.
What's Next?
The new D-specs permit us to consolidate data definitions in a single place in our programs, which can make them easier to understand and modify. In addition, the OVERLAY, PREFIX and length notations provide substantial usability improvements in ILE RPG.
What does the future hold? Since we can define any field or array in D-specs, how about permitting D-specs at the start of a subroutine to define local variables? Wouldn't it be nice to be able to use fields or arrays in a subroutine and not have to worry if they are used elsewhere in the program? Perhaps we'll see local variables implemented in a future ILE RPG release.
In our next article, we will tackle I-specs, C-specs, O-specs, and introduce Built-In Functions (BIFs).
Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe and Australia. Charlie can be reached at 517-676-9700.
An Introduction to ILE RPG: Part 2
Figure 1 D-spec Layout
UNABLE TO REPRODUCE GRAPHICS
An Introduction to ILE RPG: Part 2
Figure 2 Named Constants
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 I..............Namedconstant+++++++++C.........Fldnme...................... I 'Midrange Computing' C CMPNY I 'abcdefghijklmnopqrs- C LWR I 'tuvwxyz' I 20 C TWENTY I X'1C' C DUP
An Introduction to ILE RPG: Part 2
Figure 3 Stand-alone Fields
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. I DS I..............Ext-field+............PFromTo++DField+...................... I P 1 42PACK72 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C *LIKE DEFN PRGROS LRGROS+ 2 C *LIKE DEFN PRNAME XXNAME C MOVEL'Missing' XXNAME P P=Pad with blanks
An Introduction to ILE RPG: Part 2
Figure 4 Data Structures
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. IGLDS DS I..............Ext-field+............PFromTo++DField+...................... I 1 30 GLDESC I 31 41 GLNUM I 31 32 GLCMPY I 33 36 GLMAIN I 37 41 GLSUB I 42 44 GLCLASS I 45 48 GLCAT
An Introduction to ILE RPG: Part 2
Figure 5 Externally Defined Data Structures
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. IDSSEL EIDSOELPMNM I..............Ext-field+............PFromTo++DField+...................... I PMFNUM P2FNUM I PMTNUM P2TNUM I PMFZIP P2FZIP I PMTZIP P2TZIP CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C *INZSR BEGSR C MOVE *ALL'9' P2TNUM C MOVE *ALL'9' P2TZIP C ENDSR
An Introduction to ILE RPG: Part 2
Figure 6 Data Areas
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++..............OccrLen+............................ IINV#DS DS I............Ext-field+..............PFromTo++DField+L1M1..PlMnZr.......... I 1 70$INV# I 8 8 $ISTS CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDEHiLoEqComments+++++++...... C *NAMVAR DEFN INV#DS OEAIN Invoice # DTAARA
An Introduction to ILE RPG: Part 2
Figure 7 Run-time Array
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E DEPT 10 2
An Introduction to ILE RPG: Part 2
Figure 8 Compile-time Array
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E DEPT 1 10 2 A
An Introduction to ILE RPG: Part 2
Figure 9 Prerun-time Arrays
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E OLDDEPT TABDPT 1 100 3 0ATABTOT 9P2
An Introduction to ILE RPG: Part 2
Figure 10 Initializing an Array
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E SRT 99 10 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDEHiLoEqComments+++++++...... C *INZSR BEGSR C MOVE *HIVAL SRT C ENDSR
LATEST COMMENTS
MC Press Online