Problem: You find that a variable used in the EXPOSE statement of a procedure is not visible in your routine.
Hint: There's a bug in the processing of the EXPOSE statement in Classic REXX (not in Object-Oriented REXX!):
If you expose a stem variable directly in the EXPOSE statement and also in a variable list in parentheses the order of the parameter for the EXPOSE statement is important. Try the example below to see what I mean.
To avoid this bug, you should always specify variable lists before variable
names for EXPOSE statements
E.g. use
test: PROCEDURE expose (myVarList1) (myVarList2) myVar3 myVar4
instead of
test: PROCEDURE expose myVar3 myVar4 (myVarList1) (myVarList2)
(see also The keyword instruction EXPOSE)
/* sample code to show the bug in the processing of the EXPOSE */ /* statement in Classic REXX */ /* define some variable lists for the EXPOSE */ /* statement */ exposeList = 'test1. test2. test3.' exposeList1 = 'test1. testVar test2. test3.' /* define some variables for the EXPOSE */ /* statement */ testVar = 'Testing...' test1.0 = 2 test1.1 = 'T1_1' test1.2 = 'T1_2' test2.0 = 2 test2.1 = 'T2_1' test2.2 = 'T2_2' test3.0 = 2 test3.1 = 'T3_1' test3.2 = 'T3_2' /* show the values of the variables in the main */ /* procedure */ say 'Now in Main:' call ShowVariables /* now call the various subroutines with */ /* different EXPOSE statements. */ /* Note that all global variables should be */ /* available in all subroutines! */ call TestProc1 call TestProc2 call TestProc3 call TestProc4 return TestProc1: PROCEDURE expose (exposeList) test2. test1. testVar say 'Now in TESTPROC1: PROCEDURE expose (exposeList) test2. test1. testVar' call ShowVariables return TestProc2: PROCEDURE expose test1. (exposeList) TestVar say 'Now in TESTPROC2: PROCEDURE expose test1. (exposeList) TestVar' call ShowVariables return TestProc3: PROCEDURE expose test2. (exposeList1) say 'Now in TESTPROC3: PROCEDURE expose test2. (exposeList1) ' call ShowVariables return TestProc4: PROCEDURE expose test1. (exposeList1) say 'Now in TESTPROC4: PROCEDURE expose test1. (exposeList1) test2. TestVar' call ShowVariables return /* sample routine to show the value of all global variables */ ShowVariables: if datatype( test1.0 ) = 'NUM' then do do i = 0 to test1.0 call CharOut, 'test1.' || i || ' is "' || test1.i || '" ' end say end else say 'test1.0 is "' || test1.0 || '" (= NOT DEFINED!!!)' if datatype( test2.0 ) = 'NUM' then do do i = 0 to test2.0 call CharOut, 'test2.' || i || ' is "' || test2.i || '" ' end say end else say 'test2.0 is "' || test2.0 || '" (= NOT DEFINED!!!)' if datatype( test3.0 ) = 'NUM' then do do i = 0 to test3.0 call CharOut, 'test3.' || i || ' is "' || test3.i || '" ' end say end else say 'test3.0 is "' || test3.0 || '" (= NOT DEFINED!!!)' say 'TestVar is "' || testVar || '"' return
Here is the result from the code above executed under Classic REXX:
Now in Main: test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "2" test3.1 is "T3_1" test3.2 is "T3_2" TestVar is "Testing..." Now in TESTPROC1: PROCEDURE expose (exposeList) test2. test1. testVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "2" test3.1 is "T3_1" test3.2 is "T3_2" TestVar is "Testing..." Now in TESTPROC2: PROCEDURE expose test1. (exposeList) TestVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "TEST2.0" (= NOT DEFINED!!!) test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "Testing..." Now in TESTPROC3: PROCEDURE expose test2. (exposeList1) test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "Testing..." Now in TESTPROC4: PROCEDURE expose test1. (exposeList1) test2. TestVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "TEST2.0" (= NOT DEFINED!!!) test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "TESTVAR"