Passing information with variables

When a program and its internal subroutine or function share the same variables, the value of a variable is what was last assigned. This is regardless of whether the assignment was in the main part of the program or in the subroutine or function.

The following example shows passing information to a subroutine. The variables number1, number2, and answer are shared. The value of answer is assigned in the subroutine and used in the main part of the program.
Figure 1. Example of Passing Information in a Variable Using a Subroutine

/******************************* REXX ********************************/
/* This program receives a calculated value from an internal         */
/* subroutine and uses that value in a SAY instruction.              */
/*********************************************************************/

number1 = 5
number2 = 10
CALL subroutine
SAY answer                    /* Produces 15 */
EXIT

subroutine:
answer = number1 + number2
RETURN
The next example is the same, except it passes information to a function rather than a subroutine. The subroutine includes the variable answer on the RETURN instruction. The language processor replaces the function call with the value in answer.
Figure 2. Example of Passing Information in a Variable Using a Function

/******************************* REXX ********************************/
/* This program receives a calculated value from an internal         */
/* function and uses SAY to produce that value.                      */
/*********************************************************************/

number1 = 5
number2 = 10
SAY add()              /* Produces 15 */
SAY answer             /* Also produces 15 */
EXIT

add:
answer = number1 + number2
RETURN answer
Using the same variables in a program and its internal subroutine or function can sometimes create problems. In the next example, the main part of the program and the subroutine use the same control variable, i , for their DO loops. As a result, the DO loop runs only once in the main program because the subroutine returns to the main program with i = 6.
Figure 3. Example of a Problem Caused by Passing Information in a Variable Using a Subroutine

/******************************* REXX ********************************/
/* NOTE: This program contains an error.                             */
/* It uses a DO loop to call an internal subroutine, and the         */
/* subroutine uses a DO loop with the same control variable as the   */
/* main program. The DO loop in the main program runs only once.     */
/*********************************************************************/

number1 = 5
number2 = 10
DO i = 1 TO 5
   CALL subroutine
   SAY answer           /* Produces 105 */
END
EXIT

subroutine:
DO i = 1 TO 5
   answer = number1 + number2
   number1 = number2
   number2 = answer
END
RETURN
The next example is the same, except it passes information using a function instead of a subroutine.
Figure 4. Example of a Problem Caused by Passing Information in a Variable Using a Function

/******************************* REXX ********************************/
/* NOTE: This program contains an error.                             */
/* It uses a DO loop to call an internal function, and the           */
/* function uses a DO loop with the same control variable as the     */
/* main program. The DO loop in the main program runs only once.     */
/*********************************************************************/

number1 = 5
number2 = 10
DO i = 1 TO 5
  SAY add()          /* Produces 105 */
END
EXIT

add:
DO i = 1 TO 5
   answer = number1 + number2
   number1 = number2
   number2 = answer
END
RETURN answer
To avoid this kind of problem in an internal subroutine or function, you can use:
  • The PROCEDURE instruction, as described in the next section.
  • Different variable names in a subroutine or function than in the main part of the program . For a subroutine, you can pass arguments on the CALL instruction. See Passing information with arguments.

Protecting variables with the PROCEDURE instruction

When you use the PROCEDURE instruction immediately after the subroutine or function label, all variables in the subroutine or function become local to the subroutine or function; they are shielded from the main part of the program. You can also use the PROCEDURE EXPOSE instruction to protect all but a few specified variables.

The following examples show how results differ when a subroutine or function uses or does not use PROCEDURE.
Figure 5. Example of Subroutine Using the PROCEDURE Instruction

/******************************* REXX ********************************/
/* This program uses a PROCEDURE instruction to protect the          */
/* variables within its subroutine.                                  */
/*********************************************************************/
number1 = 10
CALL subroutine
SAY number1 number2           /* Produces 10 NUMBER2 */
EXIT

subroutine: PROCEDURE
number1 = 7
number2 = 5
RETURN
Figure 6. Example of Subroutine without the PROCEDURE Instruction

/******************************* REXX ********************************/
/* This program does not use a PROCEDURE instruction to protect the  */
/* variables within its subroutine.                                  */
/*********************************************************************/
number1 = 10
CALL subroutine
SAY number1 number2            /* Produces 7 5 */
EXIT

subroutine:
number1 = 7
number2 = 5
RETURN
The next two examples are the same, except they use functions rather than subroutines.
Figure 7. Example of Function Using the PROCEDURE Instruction

/******************************* REXX ********************************/
/* This program uses a PROCEDURE instruction to protect the          */
/* variables within its function.                                    */
/*********************************************************************/
number1 = 10
SAY pass() number2         /* Produces 7 NUMBER2 */
EXIT

pass: PROCEDURE
number1 = 7
number2 = 5
RETURN number1
Figure 8. Example of Function without the PROCEDURE Instruction

/******************************* REXX ********************************/
/* This program does not use a PROCEDURE instruction to protect the  */
/* variables within its function.                                    */
/*********************************************************************/
number1 = 10
SAY pass() number2               /* Produces 7 5 */
EXIT

pass:
number1 = 7
number2 = 5
RETURN number1

Exposing variables with PROCEDURE EXPOSE

To protect all but specific variables, use the EXPOSE option with the PROCEDURE instruction, followed by the variables that are to remain exposed to the subroutine or function.

The next example uses PROCEDURE EXPOSE in a subroutine.
Figure 9. Example Using PROCEDURE EXPOSE in Subroutine

/******************************* REXX ********************************/
/* This program uses a PROCEDURE instruction with the EXPOSE option  */
/* to expose one variable, number1, in its subroutine. The other     */
/* variable, number2, is set to null and the SAY instruction         */
/* produces this name in uppercase.                                  */
/*********************************************************************/
number1 = 10
CALL subroutine
SAY number1 number2           /* produces 7 NUMBER2 */
EXIT

subroutine: PROCEDURE EXPOSE number1
number1 = 7
number2 = 5
RETURN
The next example is the same except PROCEDURE EXPOSE is in a function instead of a subroutine.
Figure 10. Example Using PROCEDURE EXPOSE in a Function

/******************************* REXX ********************************/
/* This program uses a PROCEDURE instruction with the EXPOSE option  */
/* to expose one variable, number1, in its function.                 */
/*********************************************************************/
number1 = 10
SAY pass() number1              /* Produces 5 7 */
EXIT

pass: PROCEDURE EXPOSE number1
number1 = 7
number2 = 5
RETURN number2

For more information about the PROCEDURE instruction, see PROCEDURE.