PROCEDURE

Purpose

Read syntax diagramSkip visual syntax diagram>>-PROCEDURE--+------------------------+--;--------------------><
              |         .------------. |
              |         V            | |
              '-EXPOSE----+-name---+-+-'
                          '-(name)-'
 

PROCEDURE, within an internal routine (subroutine or function), protects variables by making them unknown to the instructions that follow it. After a RETURN instruction is processed, the original variables environment is restored and any variables used in the routine (that were not exposed) are dropped. (An exposed variable is one belonging to a caller of a routine that the PROCEDURE instruction has exposed. When the routine refers to, or alters, the variable, the original (caller's) copy of the variable is used.) An internal routine need not include a PROCEDURE instruction; in this case the variables it is manipulating are those the caller "owns." If used, the PROCEDURE instruction must be the first instruction processed after the CALL or function invocation; that is, it must be the first instruction following the label.

If you use the EXPOSE option, any variable specified by name is exposed. Any reference to it (including setting and dropping) refers to the variables environment the caller owns. Hence, the values of existing variables are accessible, and any changes are persistent even on RETURN from the routine. If name is not enclosed in parentheses, it identifies a variable you want to expose and must be a symbol that is a valid variable name, separated from any other name with one or more blanks.

If parentheses enclose a single name, then, after the variable name is exposed, the value of name is immediately used as a subsidiary list of variables. (Blanks are not necessary either inside or outside the parentheses, but you can add them if desired.) This subsidiary list must follow the same rules as the original list (that is, valid variable names, separated by blanks) except that no parentheses are allowed.

Variables are exposed in sequence from left to right. It is not an error to specify a name more than one time, or to specify a name that the caller has not used as a variable.

Any variables in the main program that are not exposed are still protected. Therefore, some limited set of the caller's variables can be made accessible, and these variables can be changed (or new variables in this set can be created). All these changes are visible to the caller upon RETURN from the routine. Example:

/* This is the main REXX program */
j=1; z.1='a'
call toft
say j k m       /* Displays "1 7 M"          */
exit

/* This is a subroutine     */
toft: procedure expose j k z.j
   say j k z.j  /* Displays "1 K a"          */
   k=7; m=3     /* Note: M is not exposed    */
   return

Note that if Z.J in the EXPOSE list had been placed before J, the caller's value of J would not have been visible at that time, so Z.1 would not have been exposed.

The variables in a subsidiary list are also exposed from left to right.

Example:

/* This is the main REXX program */
j=1;k=6;m=9
a ='j k m'
call test
exit
 
/* This is a subroutine     */
test: procedure expose (a)   /* Exposes A, J, K, and M     */
  say a j k m                /* Displays "j k m 1 6 9"     */
  return

You can use subsidiary lists to more easily expose a number of variables at one time or, with the VALUE built-in function, to manipulate dynamically named variables.

Example:

/* This is the main REXX program */
c=11; d=12; e=13
Showlist='c d'     /* but not E              */
call Playvars
say c d e f        /* Displays "11 New 13 9" */
exit
 
/* This is a subroutine     */
Playvars: procedure expose (showlist) f
 say word(showlist,2)              /* Displays "d"                     */
 say value(word(showlist,2),'New') /* Displays "12" and sets new value */
 say value(word(showlist,2))       /* Displays "New"                   */
 e=8                               /* E is not exposed                 */
 f=9                               /* F was explicitly exposed         */
 return

Specifying a stem as name exposes this stem and all possible compound variables whose names begin with that stem. (See page *** for information about stems.) Example:

/* This is the main REXX program */
a.=11; i=13; j=15
i = i + 1
C.5 = 'FRED'
call lucky7
say a. a.1 i j c. c.5
say 'You should see 11 7 14 15 C. FRED'
exit
lucky7:Procedure Expose i j a. c.
/* This exposes I, J, and all variables whose     */
/* names start with A. or C.                      */
A.1='7'  /* This sets A.1 in the caller's         */
         /* environment, even if it did not       */
         /* previously exist.                     */
return

Variables may be exposed through several generations of routines, if desired, by ensuring that they are included on all intermediate PROCEDURE instructions.

See the CALL instruction and function descriptions on pages Purpose and *** for details and examples of how routines are called.