Indexed strings and arrays
Any NetRexx string (that is, a value of type Rexx), has the ability to have sub-values, values (also of type Rexx) which are associated with the original string and are indexed by an index string which identifies the sub-value. Any string with such sub-values is known as an indexed string.
The sub-values of a NetRexx string are accessed using indexed references, where the name of a variable of type Rexx is followed immediately by square brackets enclosing one or more expressions separated by commas:[1]
symbol'['[expression[,expression]...]']'
It is important to note that the symbol that names the variable must be followed immediately by the '[', with no blank in between, or the construct will not be recognized as an indexed reference.
The expressions (separated by commas) between the brackets are called the indexes to the string. These index expressions are evaluated in turn from left to right, and each must evaluate to a value is of type Rexx or that can be converted to type Rexx.
The resulting index strings are taken 'as-is' -- that is, they must match exactly in content, case, and length for a reference to find a previously-set item. They may have any length (including the null string) and value (they are not constrained to be just those strings which are numbers, for example).
If a reference does not find a sub-value, then a copy of the non-indexed value of the variable is used.
Example:
surname='Unknown' -- default value
surname['Fred']='Bloggs'
surname['Davy']='Jones'
try='Fred'
say surname[try] surname['Bert']
would say 'Bloggs Unknown'.
When multiple indexes are used, they indicate accessing a hierarchy of strings. A single NetRexx string has a single set of indexes and subvalues associated with it. The sub-values, however, are also NetRexx strings, and so may in turn have indexes and sub-values. When more than one index is specified in an indexed reference, the indexes are applied in turn from left to right to each retrieved sub-value.
For example, in the sequence:
x='?'
x['foo', 'bar']='OK'
say x['foo', 'bar']
y=x['foo']
say y['bar']
both say instructions would display the string 'OK'.
Indexed strings may be used to set up 'associative arrays', or dictionaries, in which the subscript is not necessarily numeric, and thus offer great scope for the creative programmer. A useful application is to set up a variable in which the subscripts are taken from the value of one or more variables, so effecting a form of associative (content addressable) memory.
Notes:
- A variable of type Rexx must have been assigned a value before indexing is used on it. This is the value that is used as the default value whenever an indexed reference finds no sub-value.
- The indexes, and hence the sub-values, of a Rexx object can be retrieved in turn using the over keyword of the loop instruction.
- The exists method of the Rexx class may be used to test whether an indexed reference has an explicitly-set value.
- Assigning null to an indexed reference (for example, the assignment switch[7]=null;) drops the sub-value; until set to a new value, any reference to the sub-value (including use of the exists method) will return the same result as when it had never been set.
Arrays
In addition to indexed strings, NetRexx also includes the concept of fixed-size arrays, which may be used for indexing values of any type (including strings).
Arrays are used with the same syntax and in the same manner as indexed strings, but with important differences that allow for compact implementations and access to equivalent data structures constructed using other programming languages:
- The indexes for arrays must be whole numbers that are zero or positive. There will usually be an implementation restriction on the maximum value of the index (typically 999999999 or higher).
- The elements of an array are considered to be ordered; the first element has index 0, the second 1, and so on.
- An array is of fixed size; it must be constructed before use.
- Variables that are assigned arrays can only be assigned arrays (of the same dimension, see below) in the future. That is, being an array changes the type of a value; it becomes a dimensioned type.
Array references use the NetRexx indexed reference syntax defined above. The same syntax is used for constructing arrays, except that the symbol before the left bracket describes a type (and hence may be qualified by a package name). The expression or expressions between the brackets indicate the size of the array in each dimension, and must be a positive whole number or zero:
arg=String[4] -- makes an array for four Strings
arg=java.io.File[4] -- makes an array for four Files
i=int[3] -- makes an array for three 'int's
(Another way of describing this is that array constructors look just like other object constructors, except that brackets are used instead of parentheses.)
Once an array has been constructed, its elements can be referred to using brackets and expressions, as before:
i[2]=3 -- sets the '2'-indexed value of 'i'
j=i[2] -- sets 'j' to the '2'-indexed value of 'i'
Regular multiple-dimensioned arrays may be constructed and referenced by using multiple expressions within the brackets:
i=int[2,3] -- makes a 2x3 array of 'int' type objects
i[1,2]=3 -- sets the '1,2'-indexed value of 'i'
j=i[1,2] -- sets 'j' to the '1,2'-indexed value of 'i'
As with indexed strings, when multiple indexes are used, they indicate accessing a hierarchy of arrays (the underlying model is therefore of a hierarchy of single-dimensioned arrays). When more than one index is specified in an indexed reference to an array, the indexes are applied in turn from left to right to each array.
As described in the section on Types, the type of a variable that refers to an array can be set (declared) by assignment of the type with array notation that indicates the dimension of an array without any sizes:
k=int[] -- one-dimensional array of 'int' objects
m=float[,,] -- 3-dimensional array of 'float' objects
The same syntax is also used when describing an array type in the arguments of a method instruction or when converting types. For example, after:
gg=char[] "Horse"
the variable gg has as its value an array of type char[] containing the five characters H, o, r, s, and e.