───PROCEDURE──┬────────────────────┬───;────── │ ┌───────┐ │ │ │ │ └──EXPOSE──┴─name──┴─┘
The PROCEDURE instruction can be used within an internal routine (subroutine or function) to protect all the existing variables by making them unknown to the instructions that follow. On executing a RETURN instruction, the original variables environment is restored and any variables used in the routine (which were not exposed) are dropped.
The EXPOSE option modifies this. Any variable specified by name is exposed, so that any reference to it (including setting and dropping) is made to the environment of the variables that the caller owns. With the EXPOSE option, you must specify at least one name, a symbol separated from any other name with one or more blanks. Optionally, you can enclose a single name in parentheses to denote a subsidiary variable list. Any variables not specified by name on a PROCEDURE EXPOSE instruction are still protected. Hence, 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 will be visible to the caller upon RETURN from the routine.
The variables are exposed in sequence from left to right. It is not an error to specify a name more than once, or to specify a name that has not been used as a variable by the caller.
Example:
/* This is the main program */ j=1; x.1='a' call toft say j k m /* would display "1 7 M" */ exit toft: procedure expose j k x.j say j k x.j /* would display "1 K a" */ k=7; m=3 /* note "M" is not exposed */ return
Note that if X.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 X.1 would not have been exposed.
If name is enclosed in parentheses (blanks are not necessary either inside or outside the parentheses but can be added if desired) then, after that variable is exposed, the value of the variable is immediately used as a subsidiary list of variables. This list of variables must follow the same rules as the main list except that no parentheses or leading or trailing blanks are allowed. The variables named in a subsidiary list are also exposed from left to right.
Example:
j=1;k=6;m=9 a ='j k m' test:procedure expose (a) /* will expose j, k, and x */
If a stem is specified in names, all possible compound variables whose names begin with that stem are exposed. (A stem is a symbol containing only one period, which is the last character.
Example:
lucky7:Procedure Expose i j a. b. /* This exposes "I", "J", and all variables whose */ /* names start with "A." or "B." */ A.1='7' /* This will set "A.1" in the caller's */ /* environment, even if it did not */ /* previously exist. */
Variables can be exposed through several generations of routines, if desired, by ensuring that they are included on all intermediate PROCEDURE instructions.
Only one PROCEDURE instruction in each level of routine call is allowed; all others (and those met outside of internal routines) are in error.
Notes:
See the CALL instruction for details and examples of how routines are invoked.