Your script can call another REXX script, just as if that other script were a built-in function, or a function in your own script, passing it arguments and receiving back some value. In order to do this, the other script should be located in the same directory as the first script. It is recommended that the name of the script end with a .rex extension.

For example, if you want to call (from your main script) another script named foobar.rex, then you can call it as so:

/* Call the script and get its return value */
value = foobar.rex()

/* Call the script and throw away its return value. Note: If using
 * Reginald Lite, the CALL keyword may be omitted.
 */
CALL foobar.rex()
Of course, if the script doesn't return a value, then use the CALL keyword (or OPTIONS "C_CALL").

When you call another script, it is referred to as an External Function/Subroutine (as opposed to internal ones which are contained inside of your main script).

If you know the exact (ie, full) name of the script with its path and extension, then you can specify that. For example, assume that the script you wish to call is named "MyScript.cmd" in the directory "C:\REXX". You may call it as so:

myreturn = 'C:\REXX\MyScript.cmd'()

This can eliminate potential problems with two scripts having the same name but different extensions, or two scripts having the same name but located in different directories. Note that I placed quotes around the full script name. This prevents a SYNTAX error, because without the quotes, the unquoted colon would otherwise cause REXX to misinterpret C as a label name.

Note: If using REXX on an operating system with case-sensitive filenames, then you should always put quotes around the script's name, even if you don't specify its full name, and make sure that you type it exactly as its name appears on disk. Windows does not use case-sensitive filenames, but LINUX does.


Variables

Normally, it is not possible for a called script to access any of your script's variables. It is as if the called script had a PROCEDURE instruction at the beginning of it. But, you can pass arguments to that script, just as you would any internal function. (The called script accesses those arguments via PARSE ARG, ARG(), or USE ARG - just like your script accesses arguments passed by the user when he runs your script).

Reginald supports using the PROCEDURE EXPOSE statement at the top of the called script. You can then list the variables in the calling script that you wish to be able to access in the called script. So, it is possible for a child script to access variables in the script that calls the child.

/* Here's an example child script that sets the
 * values of the variables named MyVar, Another,
 * MyName.3, MyName.4, and MyName.2.Extra
 * in the main script.
 * Note that exposing the stem name of MyName.
 * also exposes all of its possible tails.
 */
PROCEDURE EXPOSE MyVar Another MyName.
MyVar = 1
Another = MyVar
MyName.3 = 'Jeff'
MyName.4 = 'Paul'
MyName.2.Extra = 'No one'
RETURN

Passing arguments and returning a value

The called script can use either the RETURN instruction, or the EXIT instruction to return to your script. The EXIT instruction may be used to return any data to your script in the same way as RETURN, but the called script can use EXIT to immediately return even when deeply nested in calls to its own functions.

Let's take an example of a script we'll call. It will be contained in a file named "foobar.rex". All foobar.rex does is check how many arguments were passed to it, and then it SAY's each argument. Finally, it returns the string The End to its caller.

/* Check how many args were passed from the script that called me */
args = ARG()

/* SAY those args */
DO i = 1 to args
   SAY ARG(i)
END

/* Return 'The End' to the script that called me */
RETURN 'The End'
Now let's examine a script that calls foobar.rex:
/* Call foobar, passing 3 args, and get its return */
message = foobar.rex('Arg 1', 100, MyVariable)

/* SAY its return */
SAY message
Note that if foobar.rex didn't return any value (after its RETURN keyword), then REXX would raise a SYNTAX condition with error number 45.1 in our main script, since we are attempting to use foobar's return value.

If you don't expect or need any returned value, use the CALL keyword to throw away any return value from foobar. In this case, no SYNTAX condition is raised if foobar doesn't return a value anyway.

/* Call foobar, passing 3 args, and throw away its return */
CALL foobar.rex('Arg 1', 100, MyVariable)