[comp.lang.rexx] Programming Style

JXS118@PSUVM.BITNET (Jeff Siegel, St Operator@Atherton Hall) (11/17/89)

I wasted a significant amount of time today trying to figure out why a user's
virtual machine was acting completey wacko. Turns out that they had
accidently created a file named Q EXEC. So whenever any rexx program did
a query, as in:

'Q Disk'

it wound up executing Q EXEC instead, which created a lot of confusion.
I think it would help everyone in the VM/CMS / Rexx community if people
wrote 'CP QUERY ...' (which is what they really mean) than some abbreviation
that can be misconstrued by the system. It certainly would have saved me the
time today.

+-----------------------------------------------------------------------+
| Jeff Siegel                   |            JXS118 at PSUVM            |
| 24 Atherton Hall              |                                       |
| 862-5124                      |  "No news is netsnooze........        |
+-------------------------------+---------------------------------------+

CJS@PSUVM.BITNET (11/17/89)

It is not merely a matter of style . . . it is proper coding vs.
improper coding.  (Or GOOD vs. BAD, or RUDE vs. POLITE or SMART vs.
STUPID.)

Any REXX EXEC or XEDIT macro that issues CMS and CP commands that is
going to be used by other than the author should have "ADDRESS COMMAND"
at the beginning, and should make external calls properly.

Here is an excerpt from an unfinished "REXX Programmer's Guide".

ADDRESS COMMAND and ADDRESS CMS

Here is an attempt at an explanation of when to use the ADDRESS statement
in Rexx.  Simply put, always use an "address command" statement in an
EXEC.  It will be faster and will be less likely to fail.  Here's why.

The Default

For an EXEC, the default environment to which a command is passed is CMS,
so that any interpreted line that is not a Rexx statement has the same
result as if the user typed that line on the terminal, that is, "full
command resolution".  Case does not matter, the user's synonyms are
checked, and the command can be any EXEC, module, or CP or CMS command.

EXECs with lines such as:

           l
           filel
           globalv select group list
           mytrash

may work, but are for personal use by casual CMS users, not for public
distribution.

A Rule

A general rule could be to always code "address command" at the beginning
of an EXEC, but there are always exceptions, so the programmer must
understand CMS.

Usually one wants to be sure that CMS commands like GLOBALV, MAKEBUF,
LISTFILE, and so on, are exuecuted, and not a user synonym or EXEC with
the same name.

The statement "address command" (a synonym is address '') implies "basic
CMS SVC 202 command resolution", which essentially bypasses user synonyms
and EXECs with the same name as modules or CMS commands.  The command has
to be in upper case and should be in quotes so the value of a Rexx
variable is not substituted.  EXECs must have EXEC in front, since
"implied EXEC" is effectively off, and CP commands must have CP in front,
since "implied CP" is also effectively off.

The SVC 202 command resolution is also significantly faster than full CMS
command resolution.

Exceptions

Sometimes it is desirable to have full CMS command resolution.  Executing
a user-supplied command is a common example:

       say 'Enter a command, bozo:'
       parse external Cmd
       address 'CMS' Cmd

We cannot think of other reasons to use address CMS, other than pure
laziness.  Someone once commented that they use address CMS so that error
messages would be displayed on the screen.  But, the only message that
would be displayed is FILE NOT FOUND by ERASE, LISTFILE, RENAME, and
STATE.

This may be useful in development, but we think production EXECs should
check return codes from CMS command and take appropriate action, and we
don't think a production EXEC should let users see system error messages.

XEDIT

An XEDIT macro is a little different.  The command environment defaults
to XEDIT.  To issue a CMS command that does not display anything, address
command should be used:

      address '' 'GLOBALV SELECT BIPBOP GET SLIPSLAP'

XEDIT will not refresh the screen because it did not know a command was
issued to CMS.  When an XEDIT macro causes the screen to blink, it is
usually because a CMS command was issued without "address command".

For years, those with ASCII terminals have been unaware of this because
Yale ASCII is smart enough to know the screen hasn't been changed, so IT
doesn't re-paint it.  (But as some of us know, the I/O still takes
place!)

When issuing CMS commands that output to the terminal, the XEDIT command
CMS is better:

      'CMS EXEC NAMES'

XEDIT will refresh the screen after the command because it does not know
what the command did.

CP Commands

Nearly always, an EXEC or XEDIT macro that issues a CP command needs to
obtain the output of the command or, at least, check the return code.
The Rexx functions DIAG and DIAGRC are most convenient for this.  (A
"diagnose" instruction is the way a virtual machine can request a CP
service; diagnose instruction number 8 is a "console function", that is,
a command that is usually typed on the terminal.)

The output from the DIAG function is returned to the Rexx program rather
than the terminal.

One can code:

     call diag 8,'Q DETACH 100'

for which no output returned or checked.  Better would be:

     R = diag(8,'Q DETACH 100')
     /* now check R for messages */

Even better is:

     parse value diagrc(8,'Q DETACH 100') with cprc . msg
     if cprc <> 0 then . . .        /* Command failed */

There is seldom a reason to issue a CP command from Rexx like:

     'CP Q TIME'

unless you want the user to see the output from the command.

jj@jhunix.HCF.JHU.EDU (Jim Jones) (11/18/89)

In article <89320.222332JXS118@PSUVM.BITNET> JXS118@PSUVM.BITNET (Jeff Siegel, St Operator@Atherton Hall) writes:
>I wasted a significant amount of time today trying to figure out why a user's
>virtual machine was acting completey wacko. Turns out that they had
>accidently created a file named Q EXEC. So whenever any rexx program did
>a query, as in:
>
>'Q Disk'
>
>it wound up executing Q EXEC instead, which created a lot of confusion.

 You raise a good point here, but your example isn't entirely accurate...

 Non-VM/CMS people might want to stop reading this.  As far as I know, this
 info is VM-specific.  The best way to avoid the kinds of problems that you're
 describing (which most definitely should be avoided), is to include the line:

 address command;

 at the very start of all your Rexx programs.  You'll have to do a little
 extra work as the programmer, but so what?  Your code will be easier to
 understand and will run faster as well.  The "extra work" consists of:

 - adding a CP prefix to CP commands you want to execute

 - adding an EXEC prefix to any EXEC's you want to run (unless you use
   the "call" statement, or invoke them as Rexx functions) 

 - converting commands and their parameters/options to upper case before
   executing them

 For example, to issue the command you mentioned, you would have to code
 "QUERY DISK"  or "Q DISK"  but *not* "Q Disk" or "Query disk" etc...

 A CP commands example,    "CP Q SET"  not  "Q Set"

 An EXEC example,    "EXEC MAIL"  not  "Mail"

 If you don't convert the commands to upper case, they won't be recognized
 by CMS.  If you don't upcase (to invent a verb...) the command parameters
 and options they either won't be recognized or will do odd things, so be
 careful.  CMS really will do exactly what you tell it, even if you didn't
 want it to do so.  So that "LISTFILE * exec" will search for all files
 with a filetype of "exec" and (most likely) not find any.  If you didn't
 code the "address command" line in your EXEC it would work exactly as you
 expect and search for files with a filetype of "EXEC" (having converted
 the parameter to upper case for you).

>I think it would help everyone in the VM/CMS / Rexx community if people
>wrote 'CP QUERY ...' (which is what they really mean) than some abbreviation
>that can be misconstrued by the system. It certainly would have saved me the
>time today.

 Without "addrress command" you're still not safe.  What if the user had
 a "CP EXEC" on their 191 disk?  The 'CP QUERY ...' would still not do
 what you wanted.  And just for completeness sake, "Q DISK" is a CMS 
 command, not a CP command.

 Of course nothing is perfect, people can always create EXEC's and MODULES
 on their private disks which are named the same thing as something on the
 system.  But using "address command" should cut down on those types of
 conflicts.  And as I said, you'll get a significant performance boost
 because all the "extra work" you've done means that the system doesn't
 have to do it for you.

>+-----------------------------------------------------------------------+
>| Jeff Siegel                   |            JXS118 at PSUVM            |
>| 24 Atherton Hall              |                                       |
>| 862-5124                      |  "No news is netsnooze........        |
>+-------------------------------+---------------------------------------+

 -jj

 BTW -- The "address command" hint applies to Rexx EXEC files.  You probably
 don't want to start an XEDIT macro that way!

PJB900@PSUVM.BITNET (VM Weenie) (11/18/89)

In article <89321.090814CJS@PSUVM.BITNET>, <CJS@PSUVM.BITNET> says:

 CJS posted some useful tips and suggestions.  I'd like to  follow up on
 a few of those.

>> It is not merely a matter of style . . . it is proper coding vs.
>>improper coding.  (Or GOOD vs. BAD, or RUDE vs. POLITE or SMART vs.
>>STUPID.)
>>
>>Any REXX EXEC or XEDIT macro that issues CMS and CP commands that is
>>going to be used by other than the author should have "ADDRESS COMMAND"
>>at the beginning, and should make external calls properly.

>Here is an excerpt from an unfinished "REXX Programmer's Guide".
>The statement "address command" (a synonym is address '')

 Don't forget the null string!  "address" by itself is not the same thing.
 Without the null you just switch to the previous environment.

 It's also a good idea for the REXX EXEC or XEDIT macro to leave the
 calling environment unchanged unless of course that's what it's for.
 No mucking around with the stack unless ya leave it like ya found it!
 Suggestion: 'MAKEBUF' on entering and 'DROPBUF' on leaving.
 GLOBALs and SETs should be restored before leaving.


CJ points out the benefits of having EXECs work with CMS return codes.
Same thing goes for XEDIT.  Macros should use the XEDIT return codes.

  PLEASE include comments and  signal on error,
signal on novalue, etc for those of us who try to debug a virtual machine
after some freshman mucked around with your cute EXEC.
Also, will the EXEC function correctly in CMS subset?  If not, PLEASE
document the fact.

It's nice to know that your program is making the rounds and everybody
thinks it's really neat but sooner or later it's going to cause problems
after it's been passed around among the users a few hundred times.

Geez, I didn't mean to sound like Chuck Hannum. Sorry about that.

- Peter

JXS118@PSUVM.BITNET (Jeff Siegel) (11/18/89)

My thanks to the several people that pointed out items I had missed in the
original article. You might be amused to know that the offending program that
prompted me to write that article was actually written by a high-ranking
employee of our Computer Center. I guess we're all prone to be lazy...

+-----------------------------------------------------------------------+
| Jeff Siegel                   |            JXS118 at PSUVM            |
| 24 Atherton Hall              |                                       |
| 862-5124                      |  "No news is netsnooze........        |
+-------------------------------+---------------------------------------+