NetRexx variables all follow the same syntax rules, but are used in different contexts. These are:
NetRexx includes the concept of types (classes), though substantial programs and applets can be written without introducing explicit type declarations.
The type of a NetRexx variable is determined by the type of the value of the expression that is first assigned to it ('first' is determined statically by position in a program rather than dynamically). For subsequent assignments, it is an error to assign a value to a variable with a type mismatch unless the language processor can determine that the value can be assigned safely.
In practice, this means that the types must match exactly, or they must be a 'well-known' type such as Rexx, String, int, (etc.) for which safe conversions are defined. An object can also always be assigned to a type which is a superclass of the object's type.
Optionally, a stricter rule for assignment (where the types must be identical) may be applied, using OPTIONS STRICTASSIGN.
Objects in NetRexx are created by calling a 'constructor method' which has the same name as the class. The syntax for calling a constructor method is essentially the same as a function call in Rexx and other languages.
For example, if there are classes called 'ibm.util.hex', 'RunKnown', and 'Window':
hexy=ibm.util.hex(3) -- 'hexy' has type 'ibm.util.hex' rk=RunKnown() -- 'rk' has type 'RunKnown' fred=Window(10, 20) -- 'fred' has type 'Window' s="Hello world" -- 's' has type 'Rexx' j=5 -- 'j' has type 'Rexx', as if written j="5"
The last two examples above illustrate that, by default, the types of literal strings and numbers are Rexx and so variables tend to be of a Rexx type. This allows the language to remain simple and easy to learn, as many useful programs can be written solely using the Rexx type. Potentially more efficient (though of course less human-oriented) binary representations of literals can optionally be selected to be the default by using OPTIONS BINARY. In this case, in a Java environment, the types of 's' and 'j' above would have been 'java.lang.String' and 'int' respectively.
A variable may be introduced ('declared') without giving it an initial value by simply assigning a type to it:
i=int j=Window
The type of a value may be overridden (if required) by 'conversions' (sometimes called 'casting'). This syntax for a conversion is the same as the Rexx "blank operator": when the left-hand-side of a blank operator is a type (class name, perhaps with dimensions) then the operation assigns a type to the right-hand-side term of the operator. For example:
int 7.0 int 7.3**5 Exception e Complex vector
The priority (precedence) of the conversion operator is the same as when it means concatenate-with-blank; it is lower than arithmetic operators but higher than logical operators.
You can test whether the type of a given object can be converted to another type using the '<=' (or '>=') operators. For example:
if i<=Object then say 'I is an instance of Object' if String>=i then say 'I is an instance of String'
This also works for testing whether one type is the subclass (or the same as) another:
if String<=Object then say 'String is an Object'
If the conversion is known to be impossible at 'compile time', then an error will be reported at that time.
Certain types (such as 'int' in the examples above) may be defined as 'primitive' by the underlying environment, and this may affect their semantics (objects of a primitive type may be passed by value rather than by reference, for example). However, NetRexx makes no distinction of syntax for primitive types.
An implementation of NetRexx can determine automatically from knowledge of primitive types (and other factors) when an object is being constructed, so there is no 'new' operator. As in Rexx, both storage allocation and storage reclamation are automatic.
In order for types to be determined and type-checking to be possible at 'compile-time', and easily determined by inspection, variable typing is static in scope:
The type of a property is determined from the expression (which may be just a type) that is assigned to it. Properties can only be introduced before the first method in a class.
method iszero(x) if x=0 then qualifier='is zero' else qualifier='is not zero' say 'The argument' qualifier'.'
the variable "qualifier" is known throughout the method and has a value when the SAY instruction is executed.
Within a NetRexx program, variable names are caseless (for example, the names 'Fred' and 'FRED' refer to the same variable). Where public names are exposed (for example the names of properties, classes, and methods, and in cross-reference listings) the case used for the name will be that used when the name was first introduced.
[ previous section | contents | next section ]
From 'netrexx.doc', version 0.75.
Copyright(c) IBM Corporation, 1996. All rights reserved. ©