fhg
Volume 11, Number 6 -- February 16, 2011

Commands: Underused and Unappreciated

Published: February 16, 2011

by Ted Holt

As programming languages go, CL is not glamorous. Nevertheless, it is practical and effective, and it has some nice features. One of my favorite features is the ability to extend the CL language by creating my own commands. I have used this feature many times to great advantage over the years, and I am amazed that so many programmers have never written a command. In this article I discuss advantages of creating commands and give an example of how to do so.

I have noticed that many shops use the CALL command exclusively to start execution of a program. CALL works in all instances and is often sufficient. However, you can write a command as an alternative interface to a program. Running the command is the same as calling the program, but the command has certain advantages. Here are some of them.

Advantages of Commands over CALL

1. Keyword parameters are easier to read than positional parameters.

Let's say you're required to change a CL program. Which of the following two commands would you prefer to see as you read through the source code? Do you like the CALL version?

CALL PGM(MYPGM) PARM('QCUSTCDT  QIWS      ' 'CUSTOMER  QTEMP     ' +
                   '*FIRST' 'CUSTOMER' '*REPLACE')

Or the keyword version?

MYCMD FROMFILE(QIWS/QCUSTCDT) TOFILE(QTEMP/CUSTOMER) +
        FROMMBR(*FIRST) TOMBR(CUSTOMER) MBROPT(*REPLACE)

I vote for the keyword version, because it gives me a lot of information about what's going on.

2. When using keyword parameters, you don't have to leave placeholders for unnecessary parameters.

Suppose you only need to provide values for parameters 1, 2, and 10 on a call to program MYPGM. Which of the following do you like better?

CALL PGM(MYPGM) PARM(&ENDDATE &COMPANY X X X X X X X CLOSE)


MYCMD ENDDATE(&ENDDATE) COMPANY(&COMPANY) OPTION(CLOSE)

Again, I prefer the second.

3. Rules for parameter values are more relaxed when using a command than they are under CALL.

Suppose program MYPGM requires one parameter--a two-digit packed decimal company number. To call this program from another program requires that the company number match in type and size.

DCL        VAR(&COMPANY) TYPE(*CHAR) LEN(3)
DCL        VAR(&NCOMPANY) TYPE(*DEC) LEN(2 0)

CHGVAR     VAR(&NCOMPANY) VALUE(&COMPANY)
CALL       PGM(MYPGM) PARM(&NCOMPANY)

But if you call MYPGM via a command, the command processor converts the data to the required type and size for you.

DCL        VAR(&COMPANY) TYPE(*CHAR) LEN(2 0)

MYCMD      COMPANY(&COMPANY)

Say goodbye to those annoying scratch variables that clutter up your code.

4. If the command definition allows it, you may use expressions in command parameters. You may not use expressions in the PARM parameter of the CALL command.

In this example, MYPGM requires three parameters. Suppose you wish to call MYPGM using parameter values extracted from a data area. Here's how it's done with CALL.

 DCL        VAR(&DATA) TYPE(*CHAR) LEN(1024)
 DCL        VAR(&PRTTXT) TYPE(*CHAR) LEN(30)
 DCL        VAR(&COMPANY) TYPE(*DEC) LEN(2)
 DCL        VAR(&CUSTOMER) TYPE(*DEC) LEN(6)

 CHGVAR     VAR(&COMPANY) VALUE(%SST(&DATA 101 2))
 CHGVAR     VAR(&CUSTOMER) VALUE(%SST(&DATA 103 6))
 CHGVAR     VAR(&PRTTXT) VALUE(%SST(&DATA 151 200))

 CALL       PGM(MYPGM) PARM(&COMPANY &CUSTOMER &PRTTXT)

The same process is simpler when using a command that allows expressions.

DCL        VAR(&DATA) TYPE(*CHAR) LEN(1024)

MYCMD      COMPANY(%SST(&DATA 101 2)) +
           CUSTOMER(%SST(&DATA 103 6)) +
           PRTTXT(%SST(&DATA 151 30))

I used the substring function in that example. You can also concatenate. Notice the COMPANY parameter in the following example.

DCL        VAR(&DATA) TYPE(*CHAR) LEN(1024)
DCL        VAR(&COMP1) TYPE(*CHAR) LEN(1)
DCL        VAR(&COMP2) TYPE(*CHAR) LEN(1)

MYCMD      COMPANY(&COMP1 *CAT &COMP2) +
           CUSTOMER(%SST(&DATA 103 6)) +
           PRTTXT(%SST(&DATA 151 30))

5. You may specify limited validation of parameter values in a command definition. For each parameter, you may specify such things as:

  • Valid values: A list of up to 300 constants that define the only permitted values
  • Relational expression: A logical expression that defines a relationship between different parameters
  • Range: Inclusive limits within which the value of a parameter value must fall
  • Full field required: Whether or not the value of the parameter may include trailing blanks

You may also name a validity checking program in the Create Command (CRTCMD) command. This program runs before the command-processing program, and allows you to define even more stringent parameter validation.

6. Commands are not afflicted with the default parameter definitions inherent in CALL.

  • Numeric literals are passed as 15-digit packed-decimal values of five decimal places
  • Character literals of 32 bytes or less are passed as 32-byte values
  • Character literals longer than 32 bytes are passed as is

When it comes to the CMD parameter of the Submit Job (SBMJOB) command, these rules apply to variables as well. Submitting a CALL with parameters to a job queue can be a pain. But submitting a command is no big deal. The command processor straightens everything out.

7. The command processor provides a nice prompting feature, which you can use from the command line, when editing a source member, and when prompting a command parameter in another command, such as Submit Job (SBMJOB). Because of the prompter, you can do a much better job filling in the parameters properly.

An Example

Let's say you've written a wonderful program that's going to revolutionize the Accounts Receivable department. It's really more than one program; you've created three objects.

  • AR100P: An externally described printer file to define a report
  • AR100R: An RPG program with embedded SQL to select the requested data and create the report
  • AR100C: A CL program to apply print text to the printer file, call the RPG program and handle errors and messaging

Job well done!

Your super-duper application requires three values to be supplied at run time.

  • A two-digit company number, indicating which company is to be reported.
  • A six-digit customer number. If this value is positive, the customer assigned that account number will be the only customer on the report. If this value is zero or negative, all customers of the selected company will appear on the report.
  • A 30-character string of text, which will print at the bottom of each page of the report.

Here are some pieces of the CL program showing the parameter definitions.

pgm parm(&inCompany &inCustomer &inPrtTxt)

dcl   &inCompany     *dec       2
dcl   &inCustomer    *dec       6
dcl   &inPrtTxt      *char     30
dcl   &Status        *char      8

ovrprtf ar100p prttxt(&inPrtTxt)
call    ar100r parm(&inCompany &inCustomer &Status)
dltovr  ar100p

if (%sst(&Status 4 5) *ne '00000') do
   sndpgmmsg  msgid(cpf9898) msgf(qcpfmsg) msgtype(*diag) +
                msgdta('Program' *bcat &PgmName *bcat +
                       'ended abnormally with status' *bcat &Status)
   goto Escape
enddo

You've been asked to place several invocations of this application--one for each company--on the job scheduler to run overnight throughout the week. There's no good way to do this using CALL, due to the lengths of the company and customer parameters.

However, if you'll define a command to run the CL program, scheduling the job will be easy. Here's the source for command AR100:

CMD        PROMPT('Accounts Receivable Report')
PARM       KWD(COMPANY) TYPE(*DEC) LEN(2 0) REL(*GT 0) +
             MIN(1) PROMPT('Company')
PARM       KWD(CUSTOMER) TYPE(*DEC) LEN(6 0) DFT(*ALL) +
             REL(*GT 0) SPCVAL((*ALL -1)) +
             PROMPT('Customer')
PARM       KWD(PRTTXT) TYPE(*CHAR) LEN(30) EXPR(*YES) + 
             PROMPT('Print text')

Here's how to create the command:

CRTCMD CMD(MYLIB/AR100)
       PGM(*LIBL/AR100C)
       SRCFILE(MYLIB/QCMDSRC)
       SRCMBR(AR100)

And here's how to schedule it to run:

ADDJOBSCDE
   JOB(AR100_3) 
   CMD(AR100 COMPANY(3) CUSTOMER(*ALL) PRTTXT('Give to Billy Ruben'))
   FRQ(*WEEKLY)
   SCDDAY(*SUN *MON *TUE *WED *THU)
   SCDTIME(230000)
   JOBD(ARJOBD)

In My Experience. . .

The example in this article includes a command that executes a CL program. I don't want to give the impression that the command-processing program has to be written in CL. It can be written in any language. However, as I think back on commands I've written over the past 25 or so years, the majority of my commands have executed CL programs.

Also, I don't want to give the impression that all programs need command interfaces. If a program has few or no parameters, or is called only from other programs, the usual CALL mechanism is adequate. My experience is that only a very small percentage of programs can benefit from a command interface. However, in the case of a program that is called from many CL programs (i.e., a utility), I find that writing a command interface, even if none is needed, enhances readability and facilitates program modification.




                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot


Sponsored By
SEQUEL SOFTWARE


SEQUEL makes Power Systems data access and analysis
available to everyone.

Easy to install, configure, and use, SEQUEL delivers the data you need,
in the format you prefer, quickly and efficiently. Create queries with
drill-down data analysis, design powerful executive dashboards,
and access databases anywhere.

SEQUEL meets all your data access and analysis needs.

Follow this link for more info!



Senior Technical Editor: Ted Holt
Technical Editor: Joe Hertvik
Contributing Technical Editors: Edwin Earley, Brian Kelly, Michael Sansoterra
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

Four Hundred Monitor Calendar:  Latest info on national conferences, local events, & Webinars
looksoftware:  Integrate IBM i apps with web services. FREE Webcast. March 9
System i Developer:  Upgrade your skills at RPG & DB2 Summit in Orlando, March 22-24


 

IT Jungle Store Top Book Picks

BACK IN STOCK: Easy Steps to Internet Programming for System i: List Price, $49.95

The iSeries Express Web Implementer's Guide: List Price, $49.95
The iSeries Pocket Database Guide: List Price, $59
The iSeries Pocket SQL Guide: List Price, $59
The iSeries Pocket WebFacing Primer: List Price, $39
Migrating to WebSphere Express for iSeries: List Price, $49
Getting Started with WebSphere Express for iSeries: List Price, $49
The All-Everything Operating System: List Price, $35
The Best Joomla! Tutorial Ever!: List Price, $19.95


 
The Four Hundred
More Software Pricing Carrots for IBM i Shops

iSam Blue Predicts Falling HA Costs

When IT Attacks: Disasters of the Technology Kind

Mad Dog 21/21: The Daily Nothing

IBM Tweaks Power Systems Deals, Enables Encryption and Web Development

Four Hundred Stuff
TPS Delivers IBM i Version of MFT Solution

Hubspan Automates B2B from the Cloud

Linoma Adds Enterprise Features to MFT Offering

App Security Vendor Addresses XSRF Attacks

TrendMicro Claims Full Coverage of 64-Bit Domino with ScanMail

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

System i PTF Guide
September 25, 2010: Volume 12, Number 39

September 18, 2010: Volume 12, Number 38

September 11, 2010: Volume 12, Number 37

September 4, 2010: Volume 12, Number 36

August 28, 2010: Volume 12, Number 35

August 21, 2010: Volume 12, Number 34

TPM at The Register
HP buys Vertica for data analytics

AMD cranks up Opteron clocks

Dell crams two four-way Opterons into cloudy server

Lenovo, NEC eye server tie-up

Rackspace nears $1bn run rate

Teradata says Ellison can't keep it down

Cisco beats diminished sales targets in Q2

Oracle and Fujitsu hook up on Sparc servers

More heads roll at AMD

Novell and HP wave SUSE x64 cluster deal

Samsung and IBM in patent pact

Argonne taps IBM for 10 petaflops super

THIS ISSUE SPONSORED BY:

SEQUEL Software
WorksRight Software
System i Developer


Printer Friendly Version


TABLE OF CONTENTS
Commands: Underused and Unappreciated

OUTQ vs. PRTDEV

Admin Alert: Six Techniques to Prevent Power i Upgrades from Slowing Down

Four Hundred Guru

BACK ISSUES




 
Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2011 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement