変数による情報の受け渡し

プログラムとその内部サブルーチンまたは内部関数が同じ変数を共用する場合、変数の値は最後に割り当てられた変数の値です。 このことは、変数への値の割り当てがプログラムの本体で行われるのか、サブルーチンまたは関数で行われるのかには依存しません。

以下の例は、サブルーチンに情報を渡す方法を示しています。 変数 number1number2、および answer は共用されています。 answer の値はサブルーチンで割り当てられて、メインプログラムで使用されます。
図1: サブルーチンを使用して変数で情報を渡す例

/******************************* 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
次の例は、サブルーチンではなく関数に情報を渡すという点を除き、上記の例と同じです。 サブルーチンでは、RETURN 命令に変数 answer が含まれています。 言語処理プログラムは、関数呼び出しを answer に格納された値で置き換えます。
図2: 関数を使用して変数で情報を渡す例

/******************************* 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
プログラムとその内部サブルーチンまたは内部関数で同じ変数を使用すると、問題が生じることがあります。 次の例では、プログラムの本体とサブルーチンが、それぞれの DO ループで同じ制御変数 i を使用しています。 その結果、サブルーチンは i = 6 を設定してメイン・プログラムに戻るため、DO ループはメイン・プログラムで 1 回しか実行されないことになります。
図3: サブルーチンを使用して変数で情報を渡すことによって発生する問題の例

/******************************* 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
次の例は、サブルーチンではなく関数を使用して情報を渡すという点を除き、上記の例と同じです。
図4: 関数を使用して変数で情報を渡すことによって発生する問題の例

/******************************* 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
内部サブルーチンまたは内部関数でこのような問題を回避するには、以下の方法を使用できます。
  • PROCEDURE 命令を使用します (次のセクションで説明します)。
  • サブルーチンまたは関数の変数に、メイン・プログラムとは異なる名前を使用します。 サブルーチンの場合、CALL 命令で引数を渡すことができます。 引数付きの情報を渡すを参照してください。

PROCEDURE 命令を使用した変数の保護

サブルーチンまたは関数ラベルの直後に PROCEDURE 命令を使用すると、サブルーチンまたは関数内のすべての変数は、サブルーチンまたは関数内のローカル変数となります。それらはプログラムのメイン部分から保護されます。 また、PROCEDURE EXPOSE 命令を使用して、指定した変数以外のすべての変数を保護することもできます。

以下の例は、サブルーチンまたは関数が PROCEDURE を使用した場合と使用しない場合の結果の違いを示しています。
図 5. PROCEDURE 命令を使用したサブルーチンの例

/******************************* 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
図 6. PROCEDURE 命令を使用しないサブルーチンの例

/******************************* 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
次の 2 つの例は、サブルーチンではなく関数を使用している点を除いて同じです。
図 7. PROCEDURE 命令を使用する関数の例

/******************************* 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
図 8. PROCEDURE 命令を使用しない関数の例

/******************************* 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

PROCEDURE EXPOSE を使用した変数の公開

特定の変数以外をすべて保護するには、PROCEDURE 命令で EXPOSE オプションを使用し、サブルーチンまたは関数に公開されたままにしておく変数を続けます。

次の例では、サブルーチンで PROCEDURE EXPOSE を使用しています。
図 9. サブルーチンで PROCEDURE EXPOSE を使用する例

/******************************* 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
次の例は、サブルーチンではなく関数で PROCEDURE EXPOSE を使用するという点を除き、上記の例と同じです。
図 10. 関数で PROCEDURE EXPOSE を使用する例

/******************************* 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

PROCEDURE命令の詳細については 、PROCEDURE を参照してください。