34. Scope of variables

The only pre-processing phase in the execution of a RXS program is a scan through the program to find all user defined variables:

All user-defined variables are made global, that is, all action blocks share a common definition of the data. A variable is user defined if the variable exists in the RXS coding and if the variable is not a general order or output from a general order.

Output variables word.x and unit.x and variables carrying output from 'sql', 'namespace' and 'prompt' input, plus variables created in imbedded coding, are visible 'downwards' in the RXS program: The variables are visible in the action block where they are created plus all action blocks contained in - or imbedded in - this action block. But do notice that word.x and unit.x are given new content whenever a new action block using default func is entered during execution of the RXS program.

RXS queues are always global.

General orders out, outfunc, outfile are local for the action block or text block at which they are stated, and are visible in blocks contained in - or imbedded in - this action block.

Remaining general orders in, func, prompt, imbed, caps etc., are local for the action block.

Example 34.1

If a general order is to receive an assignment prior to the execution of the action block, this can be accomplished using a user defined variable. All user defined variables are global.

This example uses variable w_outfunc to transport an assignment into the inner action block:

)action

w_outfunc = word('browse view', random(1, 2))

)action outfunc=w_outfunc

"What's up doc?"

)endaction

)endaction

About half the times this program is executed, the user will end in browse on output, about half the time in view.

The reason for these rather uneven principles is the possible use of RXS for code generation. A COBOL program using RXS code generation normally consists of separate islands of RXS code, separated by sequences of normal COBOL code ('dead code' as seen from the RXS program). This is because you do not generate the whole COBOL coding; but only the parts of the program that is to reflect some specification file. These separate islands of RXS code must be able to communicate, therefore the use of global variables. A schema of clean inheritance of variables will not do.


34a. 'Signal on novalue'

A variable in RXS is not to be referenced before it is assigned a value. Violating this rule will cause the program to end in error.

This strict rule helps finding typing errors in the program. It also helps finding errors caused by referencing the variable in an action block outside the variable's scope.

Example 34.2:

When writing:

)action

do 5

if x = 'x' then x = 0

x = x + 1

say x

end

)endaction

the RXS program will end in error, giving an error message in line 3: "x has no value".

To see if a variable has a value or not, use the following logic:

)action

if symbol('x') = 'LIT' then do

say 'x does not contain a value'

end

)endaction

Notice: the variable name x used in symbol is quoted - elsewhere we would find ourselves back in the tarpit again, with the program making an immediate end saying, "x has no value".

34b. Problems using dynamically created variables

Variables created in an ISPF panel or created dynamically using the REXX interpret command are local. If such a variable is referenced in the RXS codning, no problem, the variable is global. But if the variable is dynamically named in the RXS coding and therefore indirectly referenced, the variable remains local. The problem also occurs if dynamically created variables are used in a prompt in RXS.

Using the RXS instruction

make_global 'varname'

to make such a variable visible in other action blocks. This instruction must be issued before any reference of the variable, and before any reference in an ISPF panel.

Example 34.3

Using dynamically named variables in RXS:

)action

do ix = 1 to 20

  make_global 'ourvar'ix

end

  )action address='tso'

  "display panel(ourpan)" /* having input fields for ourvar1, ourvar2, etc */

  )endaction

  )action 

  do ix = 1 to 20

    stmt = 'say ourvar'ix

    interpret stmt                   

)endaction

)endaction

The variables ourvar1, ourvar2, etc are never explicitly mentioned in the RXS coding, therefore the first action block must issue an 'make_global' to make the RXS coding work.