A stem is a symbol that contains a single period as the last character of the name. It cannot start with a digit.
These are stems:
The value of a stem is always a Stem object. (See
Section 5.3.15, “The Stem Class”.) The stem variable's Stem object is automatically created the first time you use the stem variable or a compound variable (
Section 1.13.5, “Compound Symbols”) containing the stem variable name. The Stem object's assigned name is the name of the stem variable (with the characters translated to uppercase). If the stem variable has been assigned a value, or the Stem object has been given a default value, the assigned name overrides the default stem name. A reference to a stem variable will return the associate Stem object.
When a stem is the target of an assignment, the action taken depends on the value being assigned. If the new value is a Stem object, the new Stem object will replace the Stem object that is currently associated with the stem variable. This can result in multiple stem variables referring to the same Stem object, effectively creating a variable alias.
Example 1.24. Stems
hole. = "empty"
hole.19 = "full"
say hole.1 hole.mouse hole.19
/* Says "empty empty full" */
hole2. = hole. /* copies reference to hole. stem to hole2. */
say hole2.1 hole2.mouse hole2.19
/* Also says "empty empty full" */
If the new value is not a Stem object, a new Stem object is created and assigned to the stem variable, replacing the Stem object currently associated with the stem variable.
The new value assigned to the stem variable is given to the new Stem object as a default value. Following the assignment, a reference to any compound symbol with that stem variable returns the new value until another value is assigned to the stem, the Stem object, or the individual compound variable.
Example 1.25. Stems
hole. = "empty"
hole.19 = "full"
say hole.1 hole.mouse hole.19
/* says "empty empty full" */
Thus, you can initialize an entire collection of compound variables to the same value.
You can pass stem collections as function, subroutine, or method arguments.
Example 1.26. Stems
/* CALL RANDOMIZE count, stem. calls routine */
Randomize: Use Arg count, stem.
do i = 1 to count
stem.i = random(1,100)
end
return
The USE ARG instruction functions as an assignment instruction. The variable STEM. in the example above is functionally equivalent to:
stem. = arg(2)
USE ARG must be used to access the stem variable as a collection. PARSE and PARSE ARG will force the stem to be a string value.
Stems can also be returned as function, subroutine, or method results. The resulting return value is the Stem object associated with the stem variable.
Example 1.27. Stems
/* RANDOMIZE(count) calls routine */
Randomize: Use Arg count
do i = 1 to count
stem.i = random(1,100)
end
return stem.
When a stem. variable is used in an expression context, the stem variable reference returns the associated Stem object. The Stem object will forward many object messages to it's default value. For example, the STRING method will return the Stem object's default value's string representation:
Example 1.28. Stems
total. = 0
say total. /* says "0" */
The [] method with no arguments will return the currently associated default value. variables can always be obtained by using the stem. However, this is not the same as using a compound variable whose derived name is the null string.
Example 1.29. Stems
total. = 0
null = ""
total.null = total.null + 5
say total.[] total.null /* says "0 5" */
You can use the DROP, EXPOSE, and PROCEDURE instructions to manipulate collections of variables, referred to by their stems.
DROP FRED.
assigns a new Stem object to the specified stem. (See
Section 2.5, “DROP”.)
EXPOSE FRED.
and
PROCEDURE EXPOSE FRED.
expose all possible variables with that stem (see
Section 2.7, “EXPOSE” and
Section 2.19, “PROCEDURE”).
The DO instruction can also iterate over all of the values assigned to a stem variable. See
Section 2.4, “DO” for more details.
Notes:
When the ARG, PARSE, PULL, or USE instruction, the VALUE built-in function, or the variable pool interface changes a variable, the effect is identical with an assignment.
Any clause that starts with a symbol and whose second token is (or starts with) an equal sign (=
) is an assignment, rather than an expression (or a keyword instruction). This is not a restriction, because you can ensure that the clause is processed as a command, such as by putting a null string before the first name, or by enclosing the expression in parentheses.
If you unintentionally use a Rexx keyword as the variable name in an assignment, this should not cause confusion. For example, the following clause is an assignment, not an ADDRESS instruction:
Address="10 Downing Street";
You can use the VAR function (see
Section 7.4.72, “VAR”) to test whether a symbol has been assigned a value. In addition, you can set SIGNAL ON NOVALUE (
NOVALUE
) to trap the use of any uninitialized variables (except when they are tails in compound variables or stem variables, which are always initialized with a Stem object when first used.)