This document describes
Index: | |
---|---|
|
|
Observe: square brackets are used in two ways within this document. Generally, these indicate that the enclosed syntactic elements are optional. Alternatively, square brackets can be specified within expression syntax. These latter brackets are shown larger than the associated text, and in dark red. You will be able to easily recognize these larger square brackets. The normal size square brackets always enclose optional syntactic elements.
![]()
![]()
![]()
![]()
|
A program source file consists of:
A program can optionally use
When additional
Note: r4 extensions are described in the separate R4.HTM document.
Although
A
A
The msgbox example is a
[ className : ] class [ extends baseClass [ explicitly ] ] |
This instruction defines the characteristics of class className. A class instruction
is optional within a class source file. When the class instruction is absent, the class
is a simple
When present, the class instruction must be the first instruction in its source file. Only one class definition is permitted per class source file. The className label is recommended, although optional, on the class instruction. The class is instantiated by its source file name. To help other programmers, or yourself, the className label should correspond to the source file name. For example:
source file: | c:\roo\secondBase.roo |
class instruction: | secondBase : class extends firstBase |
The file name portion of the class source file name, in upper case, symbolically references the class. For example, if the source file name is "c:\roo\secondBase.roo", the symbolic class name will be secondbase. A request for another class file that has the same symbolic class name will use the prior class definition, even if it is in another directory, or has a different extension. Thus, "c:\somewhereElse\secondBase.xyz" will use the class definition in "c:\roo\SECONDbase.roo" if it was previously activated. This is because the symbolic class names for both of these files match.
Suggestion: when you prepare a new class source file always check to see if another file with the same symbolic class name exists. Be aware the other file may be located in the directories associated with the ROOPATH environment variable.
When the extends phrase is specified the current class is a derivative of baseClass. The baseClass is located by a program search, with an implicit default class extension unless an explicit extension is specified within the baseClass term. The baseClass can also be an explicit file system name; such as, "c:\roo\first base.roo".
Normally, the base class is constructed before the current class is initialized. When the explicitly keyword is specified, the initialize method of the current class is activated before the base class is constructed. The base class is constructed explicitly when the following instruction is performed in the initialize method.
'base' ^ initialize[( [ argument, argument, ... ] )] |
When the base class is not explicitly constructed, the same arguments are passed to the initialization methods of the base class, and then the deriving class, in the same sequence. When the base class is explicitly constructed the arguments that are passed to the base class initialization method can be dynamically prepared, or rearranged, by the deriving class.
None of the base class methods should be used until the base class is initialized. If an initialize method in a deriving class does not explicitly initialize the base class, then the base class is implicitly initialized when the initialize method of the deriving class concludes.
Observe: as mentioned earlier, class definitions are reused until all class instances conclude. Changes to
the associated source file will not be effective while class instances are active. Often, it will be necessary to halt
the
There are three types of
Note: unlike other programming languages,
local variableName [ variableName ... ] |
The local instruction identifies one or more variables that are locally persistent for the methods within the current class source file. A separate collection of local variables is established for each class instance. The variableName values are either simple variable names, or compound stem variable names. Simple variable names do not contain a period. Compound stem variable names contain one period, which is the last character in the name.
Multiple local instructions are permitted within a class source file. Often a single local instruction is present at the beginning of the file. However, a local instruction can be placed anywhere within the file. Local variables can be declared adjacent to the point of use. It is not an error to declare the same variable as a local variable multiple times.
shared variableName [ variableName ... ] |
The shared instruction identifies one or more variables that are persistently shareable by the methods of all classes within a class hierarchy. A separate collection of shared variables is established for each class instance. The variableName values are either simple variable names, or compound stem variable names. Simple variable names do not contain a period. Compound stem variable names contain one period, which is the last character in the name. A class that is a refinement of another class must declare the variables that it is sharing; otherwise, confounding problems would arise. For example, what had been a temporary variable, in a method of a derived class, could accidentally become a shared variable as a result of a subsequent addition of the variable to the list of shared variables within the base class.
Multiple shared instructions are permitted within a class source file. Often a single shared instruction is present at the beginning of the file. However, a shared instruction can be placed anywhere within the file. Shared variables can be declared adjacent to the point of use. It is not an error to declare the same variable as a shared variable multiple times.
static variableName [ variableName ... ] |
The static instruction identifies one or more variables that are shared by all instances of a class definition. Static variables have class scope, instead of instance scope. The variableName values are either simple variable names, or compound stem variable names. Simple variable names do not contain a period. Compound stem variable names contain one period, which is the last character in the name.
Multiple static instructions are permitted within a class source file. Often a single static instruction is present at the beginning of the file. However, a static instruction can be placed anywhere within the file. Static variables can be declared adjacent to the point of use. It is not an error to declare the same variable as a static variable multiple times.
Static variables can be initialized by a preinitialize method. A corresponding finalize method allows resources that are stored in static variables to be properly terminated.
Note: it is erroneous to declare a variable in more than one class variable group. For example, it is incorrect for a variable to be declared both shared and local, or shared and static. When a conflicting variable definition is encountered the following syntax error condition is raised.
Note: when a local, shared, or static variable name is a compound symbol name the following syntax error condition is raised.
methodLabel : [ method ]
parse arg argument, argument ... . . (etc.) . return result |
A method definition is similar to a Classic Rexx internal procedure, without a variable exposure phrase. As indicated, the method instruction is optional, although recommended. When present, it is annotative, and helpful for program readers. All labels within the class source file are eligible for method invocation. These are also eligible targets for signal instructions. As in Classic Rexx programs, an unexpected method instruction is an error (code #17 -- unexpected procedure or method).
Observe: when the method instruction is absent, it is possible for program execution to flow into the method. This may introduce a logic flaw. Generally, you should use the method keyword, to avoid unexpected control flow transitions.
Unlike Classic Rexx internal procedures, methods are not invoked by the call instruction or by function calls. Methods are accessed by new invocation techniques. Methods can be invoked by either a prefix operator, or an infix operator.
[ classInstanceReference = ] ^^ classFileName[( [ argument [, argument ... ] ] )] |
The ^^ prefix operator creates an instance of the class that is
defined in classFileName.
The classFileName is located by a program search,
with an implicit default class extension
unless an explicit extension is specified within the classFileName term.
The classFileName can also be an explicit, quoted file system name; such as,
When the parenthesized argument list is omitted, and classFileName is unquoted, the class file name is the value of the variable named classFileName. The example program named qt.rooProgram creates a class which is the value of variable outputEmitter.
During instance creation the initialize method of the class is implicitly invoked. The optional arguments within the parentheses are passed as parameters to the initialize method. If the initialize method returns the empty string, the instance is created. Any other result from the initialize method is considered an error, and consequently the class instance is not created.
The resulting classInstanceReference is set to an error message if an error occurs during instance creation. Otherwise the classInstanceReference can be used to invoke various class methods.
The classInstanceReference can be assigned to multiple Rexx variables -- via assignment (=), arg, parse, and pull instructions. The classInstanceReference can also be passed as a parameter during a method invocation, or in a subroutine or function call. In turn, the parameter value can be assigned to variables in the target method, subroutine, or function. Each time the classInstanceReference is assigned to a Rexx variable, the number of uses of the class instance is incremented. When each of these variables is deactivated (via a drop instruction or method/procedure termination) the number of uses of the class instance is decremented. When the number of class instance uses is zero the class instance is discarded. The terminate method is implicitly invoked during class instance removal.
Note: there is no corollary to the ^^ operator -- i.e. a destroy operator. A class instance is only removed when the number of active instance uses reaches zero.
The ^^ operator is pronounced as the double-hop operator. The ^^ operator has the same precedence as other Rexx prefix operators.
It is possible to use the resulting classInstanceReference directly in a Rexx expression wherever a term is expected, without assigning it to a variable. In this case, the number of class instance uses is temporarily incremented during the evaluation of the current instruction, and then decremented when the instruction completes.
Here are several examples that show how a classInstanceReference can be used directly in a Rexx expression.
say ^^ vector( 'abracadabra', 'open sesame', 'shazam' ) ~ toDelimitedString( ' !! ' ) caption = ^^ vector( 'abracadabra', 'open sesame', 'shazam' ) ~ toDelimitedString( ' !! ' ) ^^ serverRequest( server, port, request ) ~ showResult |
Using a classInstanceReference directly in a Rexx expression is EXPOSED to potential syntax errors, if the class instance is not properly initialized. The syntax error can be avoided by enabling a signalled OBJECTION condition handler as shown in the example.
When the resulting classInstanceReference is set to an error message it is formatted as follows:
OBJECTION, class: classFileName, initialize method note: initializationMethodReturnValue |
classFileName is the name of the class that was initialized.
initializationMethodReturnValue is the text that is returned by the initialize method.
classInstanceReference ~ methodName[( [ argument [, argument ... ] ] )]
|
Methods are invoked with either a prefix ^ operator, or an infix ~ operator. A prefix ^ operator can be used to invoke methods within the current class context. These methods can be in the current class, a base class, or a derived class. An infix ~ operator is used to invoke instances in other class contexts. An infix ~ operator is preceded by an instance reference.
Note: the caret and tilde characters are unused in Classic Rexx.
Hint: to help you distinguish between the ^ and ~ operators, the ^ and ^^ are both prefix operators, whereas a ~ is an infix operator. You learned about the ^^ prefix operator in the class instance creation section above.
The tilde operator is not a true Rexx operator. Like other Rexx operators, spaces before and after the tilde are discarded, in the normal way. Yet, the tilde binds strongly to its left and right elements, producing a Rexx term. The classInstanceReference on the left side of the tilde can be determined as the value of an expression.
The following example shows how the tilde operator binds to its adjacent elements. The value of v ~ size is treated as a term.
v = { }
if 0 = v ~ size // 2 then
say 'An empty vector has an even size.'
|
Observe: prefix operators have a higher precedence than the tilde operator. Consequently, you will have to enclose the method invocation in parentheses to avoid having the method name processed by a prefix operator. Here is an example of an invalid invocation expression.
stk = ^^ stack( 'a', 'b', 'c' ) do while \ stk ~ isEmpty /* WRONG: this performs ( \ stk ) ~ isEmpty */ say stk ~ pull end |
Here is the corrected version:
stk = ^^ stack( 'a', 'b', 'c' ) do while \ ( stk ~ isEmpty ) /* Correct: this performs \ ( stk ~ isEmpty ) */ say stk ~ pull end |
Hint: built-in aggregate classes, such as the stack class, also have an isNonEmpty method. This method is preferred for use in loops, because it avoids the difficulty associated with the not (\) prefix operator. Here is the code again, which uses the isNonEmpty method.
stk = ^^ stack( 'a', 'b', 'c' ) do while stk ~ isNonEmpty /* this is correct, and easier to program ! */ say stk ~ pull end |
The classInstanceReference is a value that was returned from a class instance creation request.
The classInstanceReference can also be one of the following:
'base' | invokes a method in a base class |
'self' | invokes a method in the current class, or a base class but not in a derived class |
Observe: that the words self and base are enclosed in quotes above, because self and base are not reserved keywords. If these are unquoted, they are simple symbols. Unusual surprises could be in store if these symbols are assigned values!
The single caret operator has the same precedence as other Classic Rexx prefix operators -- i.e. the highest order of precedence. A prefix ^ operator is used to invoke methods in the current class, or a base class.
All methods are invoked as functions, and thus must return a result. If a result is not returned the following syntax error condition is raised: Error 44, Function (or method) did not return data.
A method in a derived class overrides a method with the same name in a base class. The base class provides a default implementation of the method. Note: the method in the derived class can explicitly invoke the base class method during processing, as follows:
doit : method /* derived class method */
parse arg argument, argument ...
. (etc.)
.
baseResult = 'base' ~ doit( 'abracadabra' ) /* invoke base class method */
return ...
|
The ^ operator is pronounced as the hop operator.
It is possible that the classInstanceReference in a method invocation could actually be a normal Rexx value instead. Rather than treating this situation as a syntax error, the expression is converted to a function call instead. For example:
'abracadabra' ~ copies( 3 )
|
is transformed to:
copies( 'abracadabra', 3 ) |
This allows the result of a method invocation to be passed to a built-in function, without embedding it within the first function parameter. Here is an example:
say obj ~ toString ~ copies( 3 ) |
This invocation technique can also be used to invoke internal and external procedures as functions. Again, the value on the left side of the tilde becomes the first argument to the procedure.
preinitialize : method
static1 = 'value' static2 = 'value' stem. = '' . . (etc.) /* do not reference LOCAL or SHARED variables here */ . return '' |
When a class is initially loaded the optional preinitialize method of the class is implicitly invoked. This method can initialize static variables. This method is invoked as a subroutine (as though CALLed), without any arguments. The preinitialize method can call other procedures within the class file as subroutines or functions. The preinitialize method does NOT have an instance context, so it cannot invoke other methods with the single caret operator (^). Also, the absence of an instance context, makes references to local, or shared variables improper. These will be resolved as normal Rexx procedure variables instead.
The preinitialize method can establish new instances with the double caret operator (^^). The returned instance values can be assigned to static variables. If returned instance values are assigned to local variables, these will be removed when the associated execution context concludes.
The preinitialize method must return a result. If the result is the empty string class creation is considered successful. Otherwise, an error string should be returned to indicate class pre-initialization was unsuccessful. The error string will be displayed to the console.
finalize : method
/* you can reference STATIC variables here */ . . (etc.) /* do not reference LOCAL or SHARED variables here */ . return '' |
When a class is removed the optional finalize method of the class is implicitly invoked, so that resources stored in static variables can be properly terminated. The finalize method can reference static variables. This method is invoked as a subroutine (as though CALLed), without any arguments. The finalize method can call other procedures within the class file as subroutines or functions. The finalize method does NOT have an instance context, so it cannot invoke other methods with the single caret operator (^). Also, the absence of an instance context, makes references to local, or shared variables improper. These will be resolved as normal Rexx procedure variables instead.
The finalize method can establish new instances with the double caret operator (^^). The returned instance values can be assigned to static variables.
The finalize method can return a result. This result is ignored.
Note: the finalize method is invoked when a class is being removed, not when a class instance is removed.
Each class has an optional initialize method.
This method is particularly important for classes that are associated with named resources -- such as: disks, directories, streams, etc. If access to these resources is unsuccessful, the initialize method can return informative error text, and the instance will no longer be active.
initialize : method
parse arg argument, argument ... . . (etc.) . return result |
When a class instance is created the initialize method of the class is implicitly invoked. This can process optional arguments that are passed from the instance creation request. The initialize method must return a result. If the result is the empty string instance creation is considered successful. Otherwise, an error string should be returned to indicate that class instance creation was unsuccessful, and an OBJECTION condition will be raised if it is enabled. The error string will be provided as the condition's description text. If the OBJECTION condition is not enabled, the error text is returned as part of the instance creation result error text.
Successful initialization of an instance can be determined by using the 'Instance' type of the datatype built-in function. An example is presented there, which shows how an incorrectly initialized class instance can be handled.
Occasionally it is helpful to return a reference to the current class instance at the conclusion of a method. This allows the calling context to invoke other instance methods subsequently within the same instruction. Various built-in class methods return a reference to the current class instance. Within methods that you develop it is very easy to return a reference to the current class instance. Here is how:
yourMethod : method . . return ^ self |
This permits the invocation context to be programmed as follows:
^^ yourClass[( [ arguments ] )] ~ yourMethod[( [ arguments ] )] ~ anotherMethod[( [ arguments ] )] |
If the special self method were unavailable, the invocation context would require multiple instructions, as follows:
obj = ^^ yourClass[( [ arguments ] )] obj ~ yourMethod[( [ arguments ] )] obj ~ anotherMethod[( [ arguments ] )] |
terminate : method
. . (etc.) . return '' |
When the number of uses of a class instance reaches zero the terminate method of the class is implicitly invoked. No arguments are available for the terminate method. The terminate method can reference and alter local, shared, and static class variables. The terminate method can create new class instances as well. The terminate method is optional.
Note: the terminate method is invoked when a class instance is removed.
This section describes extensions to the underlying Rexx language.
The following reserved keyword instructions were added:
There are four new expression operators:
^^ | instance creation, prefix operator |
^ | prefix method invocation operator |
~ | infix method invocation operator |
[ ] | array-like reference operator pair |
The OBJECTION error condition was added. This condition is raised, if enabled, when the INITIALIZE method of a class returns an error string. The INITIALIZE method's error string is provided in the information that is returned by the condition built-in function's description string. The description string also includes information about the class that was accessed.
The OBJECTION error condition is processed analogously to the NOTREADY error condition. The condition is initially disabled. It can be enabled by using either the CALL ON or SIGNAL ON instructions. An example of its use is provided below.
The following is the syntax of the instructions that enable and disable OBJECTION conditions.
call ON OBJECTION [ NAME trapLabel ]
call OFF OBJECTION signal ON OBJECTION [ NAME trapLabel ] signal OFF OBJECTION |
The following example shows how errors during class instance initialization can be bypassed by using a signal on OBJECTION instruction.
signal on OBJECTION name skipon say ^^ try( 'abra', 'ca', 'dabra' ) ^ toString skipon : |
The datatype built-in function has a minor, but important, addition -- the Instance data type. This is used to conditionally perform instructions, only if the associated object instance was properly created.
result = datatype( possibleInstanceValue, 'Instance' ) |
An additional Instance type is supported for the datatype built-in function. This returns 1 if the possibleInstanceValue argument is a class instance, and 0 otherwise.
The following shows how to assure that an instance of class abc was properly initialized.
obj = ^^ abc( 'abra', 'ca', 'dabra' ) if datatype( obj, 'Instance' ) then say obj ^ toString else do say "An error occurred creating an 'abc' class instance." say 'Error text:' obj end |
The usual Rexx technique for distinguishing commands from other instructions is generally in effect. However, when a potential command instruction contains special roo! operator characters the instruction is considered as a roo! object instruction instead. The special roo! operator characters are unquoted: square brackets ([ ]), caret (^), or tilde (~) characters. Thus, the following is not a command:
obj ~ display /* this invokes the 'display' method associated with instance 'obj' */ |
To perform the result of a method as a command, the instruction must begin with an unquoted exclamation point (!). Thus the following is performed as a command:
! obj ~ toString -- this performs a command which is
-- the result of the 'toString' method
-- associated with instance 'obj'
|
You can precede command lines, that do not contain special roo! operator characters, with an exclamation point as well. The leading exclamation point is discarded from the text before the command is performed.
Hint: if you need to start a command, that does not contain special operator characters, with an exclamation point then enclose it within quotes.
A commonly used built-in class is a vector of items. A vector class instance is prepared by normal class construction and initialization. The following is an example:
v = ^^ vector( 'a', 'b', 'c' ) |
roo! supports a shorter alternative that uses curly braces, as follows:
v = { 'a', 'b', 'c' } |
Methods can be applied after the right curly brace, as follows:
say { 'a', 'b', 'c' } ~ toString |
Vectors can be nested as follows:
vectorOfvectors = { 'a', 'b', { 'x', 'y', 'z' } } |
A vector of vectors can be composed as follows:
vectorOfvectors = { { 'a', 'b', 'c' }, { 'x', 'y', 'z' } } |
An empty vector can be prepared as follows:
e = { } |
Hint: your use of curly braces is optional. When displayed with a small font, curly braces can be difficult to distinguish from parentheses. When defining a vector, that will receive items subsequently, you may prefer to use the long hand form instead, as follows:
e = ^^ vector |
Note: the curly braces are transformed to the alternative long hand vector notation during the initial scanning phase of a roo! source file. Consequently, the long hand format will appear in trace source display output. The original source text, with the braces, will appear in the result of a sourceline built-in function request.
In an object-oriented environment it can be difficult to determine the calling context associated with an interactive trace prompt. You can request the calling context by entering the word context at an interactive trace prompt:
#nnn ? context |
Note: #nnn ? is the text of the interactive trace prompt, which shows the current source line number (nnn).
The current procedure and method calling contexts are listed. The information that is displayed uses the ContextVector built-in class. Please refer to the description of the ContextVector built-in class to interpret the information that is displayed.
Several built-in functions were added.
callback | invokes a callback function in a calling C/C++ context |
nap | takes a short snooze |
raiseObjection | raises an OBJECTION condition |
split | partitions a delimited string, returning a vector |
squareRoot | returns the square root of a number |
Observe: more built-in functions were added for NetRexx compatibility. These are described in another section below.
A callback function was added. This function is only supported when roo! is operating in DLL execution mode. The syntax of the callback function is:
result = callback( [ optionalArgument [ , optionalArgument ...etc] ] ) |
This function transfers control to a callback routine in the context that invoked the roo! DLL's 'PerformWithCallback', 'CreateClassWithCallback', or 'InvokeMethodWithCallback' entry.
Hint: a callback allows the roo! program to send information back to the calling context. In addition, the calling context can return information to the roo! program, via the result.
Click here to review the testRooDll.cpp example program that uses the DLL entry points described above.
A nap function was added. This function enables a program to pause temporarily. The syntax is:
result = nap( numberOfMilliseconds ) |
numberOfMilliseconds is a non-negative number of milliseconds to nap.
The result is a time value, which is the number of milliseconds since system startup.
A RaiseObjection function was added. This enables a program to dynamically raise an OBJECTION condition, often to the calling procedure or method scope.
The RaiseObjection function is typically CALLed. The syntax is:
call raiseObjection conditionErrorText [, additionalInformation ] |
The RaiseObjection function returns "1" always.
conditionErrorText is a general description of the OBJECTION condition.
additionalInformation provides optional, detailed information regarding the OBJECTION condition.
Observe: if the OBJECTION condition is enabled in the current procedure or method execution scope, it is handled locally. If the OBJECTION condition is not enabled in the current procedure or method execution scope, the current scope is concluded and the OBJECTION is passed to the higher execution scope, if it is handled in the higher scope. If the OBJECTION condition is not handled at all, it is treated as a SYNTAX condition in the current execution scope.
Note: the NetRexx language uses the signal instruction to raise objections in a similar manner.
The split function partitions a string into a vector of segments. The syntax is:
result = split( string, separator ) |
separator must not be an empty string.
The result is a vector, which contains the segments of string that are divided by separator.
The following is an example of usage of the split function.
say split( 'abra ca dabra', ' ' ) ~ join( '0a'x ) -- shows words vertically |
The separator can contain more than one letter. For example:
say split( 'abracadabra', 'cad' ) ~ join( ' ' ) -- shows: abra abra |
Hint: join is an alias of the toDelimitedString method in the vector built-in class.
Observe:The split function is equivalent to:
result = ^^ vector ~ addDelimitedString( string, separator ) |
Note: the split function emulates the function with the same name in JavaScript, and Perl. Similarly, the join method in the vector built-in class emulates the converse functionality that is used in these other languages. The join method prepares a delimited string from a vector of strings.
A squareroot function was added. The syntax is:
result = squareroot( number ) |
number must be non-negative.
roo! provides the following capabilities which were innovations of the NetRexx programming language.
double-hyphen line comments "--"
roo! supports normal Rexx comment capabilities. A normal Rexx comment begins with a slash-asterisk combination (/*), and concludes when a subsequent asterisk-slash combination is encountered (*/). Normal Rexx comments can be nested. In addition, normal Rexx comments can be used for line continuation.
In addition, roo! supports line comments that are triggered by a double-hyphen combination (--). This causes the remainder of the source line to be considered as commentary text, and thus is ignored. For example:
v = { 'a', 'b', 'c' } -- this is a vector containing three items |
The text that follows the double-hyphen above is commentary.
additional built-in functions
changestr, countstr, exists, lower, upper.
result = changestr( string, value, replacement ) |
The changestr function replaces each unique, non-overlapping occurrence of value within string with the replacement.
Note: if value is an empty string the changestr function returns a copy of string.
result = countstr( string, value ) |
The countstr function counts the number of unique, non-overlapping occurrences of value within string.
Note: if value is an empty string the countstr function returns 0.
result = exists( stem, compoundIndex ) |
The exists function returns "1" if the compound variable formed by the following expression is assigned a value, and "0" otherwise.
stem || '.' || compoundIndex |
Here is an exists function example.
a.x.y = 3 say exists( 'a', 'x.y' ) -- shows: '1' |
Observe: the arguments of the exists function request above are quoted. If these were unquoted, and variables a, x, or y were assigned a value, then the value of these variables would be substituted in the function arguments. This can lead to unexpected surprises.
result = lower( string [, n [, length ] ] ) |
The lower function converts uppercase characters within string to lowercase. When only the first argument is specified, the entire string is converted to lowercase. When n is specified, the conversion begins at that position. A position of 1 is the first character. When length is specified, the conversion proceeds for that many characters.
Note: if string is an empty string the lower function returns an empty string.
Here are several lower function examples.
say lower( 'ABRACADABRA' ) -- shows: 'abracadabra' say lower( 'ABRACADABRA', 5 ) -- shows: 'ABRAcadabra' say lower( 'ABRACADABRA', 5, 2 ) -- shows: 'ABRAcaDABRA' |
result = upper( string [, n [, length ] ] ) |
The upper function converts lowercase characters within string to uppercase. When only the first argument is specified, the entire string is converted to uppercase. When n is specified, the conversion begins at that position. A position of 1 is the first character. When length is specified, the conversion proceeds for that many characters.
Note: if string is an empty string the upper function returns an empty string.
Here are several upper function examples.
say upper( 'abracadabra' ) -- shows: 'ABRACADABRA' say upper( 'abracadabra', 5 ) -- shows: 'abraCADABRA' say upper( 'abracadabra', 5, 2 ) -- shows: 'abraCAdabra' |
[ ] array-like operators
The NetRexx language introduced the ability to index array-like objects with square brackets. roo! also uses square brackets to reference composite object values. Indexing within roo! programs is somewhat similar, but may differ from the NetRexx technique.
Unlike NetRexx, indexing within roo! programs uses an approach which is more similar to that used in C, C++, Java, or C# programs. For example, roo! programs can use nested and cascading index references. Arbitrary composite items can be indexed with square brackets.
Square brackets can be used to reference or revise aggregate object values. The expression
can be used wherever a term is expected in a Rexx expression. This reference is a shorthand equivalent to:
obj ~ getAt( indexValue )
Square bracket characters are treated as operator characters. Square bracket operators have the same precedence as Rexx power operators. This allows the value which precedes a left square bracket to be determined as the value of an expression. The expression within the square brackets is evaluated as though it had been contained within parentheses. Spaces preceding a left square bracket are ignored. Spaces following a right square bracket may be significant, unless another operator causes these to be ignored.
If the item which precedes the left square bracket is not an instance, the reference is transformed into a compound symbol reference instead. This emulates a NetRexx indexed string reference, with one index value. In this case, the reference is similar to:
The instruction is actually equivalent to the result of the following value built-in function request:
value( Where:
indexValue may be a compound variable.
Observe: if the compound variable is not assigned a value, the value of simple symbol obj
becomes the value of the reference. This differs from the normal Rexx value that is substituted
for an unassigned compound variable.
Similarly, square brackets can be used within the value that precedes an assignment expression (=). The expression
is a shorthand equivalent to:
obj ~ setAt( indexValue, newValue )
If the item which precedes the left square bracket is not an instance, the reference is transformed
into a compound symbol reference instead. In this case, the instruction is similar to:
The instruction is actually equivalent to:
call value Where:
indexValue may be a compound variable.
Note: recognition of an assignment instruction is enhanced to search for the equal sign
that follows a right square bracket (]) when the second token of an instruction is a left square bracket ([).
The expression on the left side of the equal sign can have a cascade of square bracket expressions as well.
Note: array references can be nested, for example:
Note: array references can be performed in sequence, for example:
Note: the expression
within the square brackets is evaluated as though the square brackets were parentheses.
Warning: roo! does not support multiple index values
in the style that is used by NetRexx. The NetRexx approach uses commas to separate indices. In
roo!, the comma is treated as a syntax error. The following
expression is considered erroneous:
The correct way to write this in roo! is:
Or, when a compound symbol is being referenced:
11.9.3.2 Assignment instruction value indexing
11.9.3.3 Array references can be nested
11.9.3.4 Difference from NetRexx array references
obj[ index1, index2, index3 ]
obj blue-ball.gif index1 ] [ index2 ] [ index3 ]
compoundStem [ index1.index2.index3 ]
Syntax:
do ... catch [e = ] condition instruction(s) catch [e = ] condition instruction(s) finally instruction(s) end |
The NetRexx language introduced the ability to catch exceptions within do, loop, or select instructions. roo! provides similar capabilities. Unlike NetRexx, Rexx conditions (SYNTAX,OBJECTION, NOTREADY,etc) are caught instead of Java exceptions.
A sequence of catch, or finally condition handlers can be specified at the end of a do, loop, or select instruction group. catch instructions identify a specific condition to trap. The instance handle of the caught exception instance can optionally be assigned to a variable. The conditions that can be caught are:
The following is an example of catch and finally condition handlers that are at the end of a do instruction group.
do say ^^ randomSequence( 52, 1, 52, 'Unique' ) ^ toString catch e = objection -- An OBJECTION condition occurred preparing a random sequence... say split( e ~ toString, ',' ) ~ toDelimitedString( '0d0a'x ) catch halt say 'Tata...' exit 97 catch syntax say 'A syntax error occurred preparing a random sequence...' say condition( 'Description' ) exit 98 finally say 'Proceeding, regardless...' end |
A similar sequence of catch/finally handlers can be added at the end of a select instruction group as well. These follow the last instruction in the otherwise instruction sequence, and precede the end instruction associated with the select instruction.
Note: instructions between the finally and end are always executed, regardless of whether a condition was raised.
Note: trap handling is activated for the catch handlers, but not the finally handler. Thus, in the above examples trap handling is activated for the OBJECTION, HALT, and SYNTAX conditions. The ERROR, FAILURE, NOTREADY, and NOVALUE conditions are not enabled for trap handling; unless these were enabled elsewhere in the program. So, in the above example the finally handler only receives control when the do instruction group concludes.
Observe: when the context of the encapsulating catch handling group (DO/LOOP/SELECT) concludes, the state of condition handling is restored to its prior setting -- CALL/SIGNAL ON/OFF. The mixing of catch handling and CALL ON/OFF, SIGNAL ON/OFF is discouraged. Results may differ from expectations when the two styles of condition handling are used.
Warning: C/C++ programmers should observe that processing of the finally group is not similar to a catch( ... ) exception handler. Processing of the finally group is implemented according to the corresponding notion within the Java or C# languages. Instructions within the finally group are always performed when the context of the containing do/loop or select group concludes. Thus, even if a return or exit instruction is performed anywhere within the context, of the containing do/loop or select group, the finally group is still performed. This includes when a return or exit instruction is performed within an associated catch handler. In the example above, the finally group is performed either after the say instruction is performed, or after any of the condition catch handlers concludes.
Similarly, the finally group is performed within a do/loop group when a leave instruction causes the loop to be exited.
The following example loops over all the indices associated with the randomSequence instance obj.
obj = ^^ randomSequence( 52, 1, 52, 'Unique' ) loop index over obj say index'.' obj[ index ] end |
When the loop over instruction is initially encountered the available set of object indices are obtained by invoking either an object's size or the getindices method. The resulting size, or vector of indices, is cached within the roo! interpreter. If the size method is defined, the indexing variable is assigned a value from 1 to the size, until the size is exceeded. Otherwise, when the getindices method is defined, the indexing variable is assigned an index from the set, one by one, during each cycle of the loop.
Observe: the indices that are available with the object may vary, as a consequence of instructions that are performed within the loop. Consequently, all items may not be processed as expected. In addition, when an index is no longer available an objection condition will be raised.
The term that follows the over can optionally be an expression. The second loop instruction in the following example loops over an object that is the value of an expression.
Array_3x3 = { { 1, 2, 3 }, { 2, 4, 6 }, { 3, 6, 9 } } loop ix over Array_3x3 loop jx over Array_3x3[ ix ] say 'Array_3x3 [' ix '] [' jx '] -- ' Array_3x3[ ix ][ jx ] end end |
Similarly, the loop over instruction can be used with a compound stem group. When the instruction is first encountered all of the names of compound variables that follow the stem are cached. And, the indexing variable is assigned one of these names during each loop cycle. Here is an example:
color.apple = 'red' color.orange = 'orange' color.banana = 'yellow' loop fruitName over 'COLOR.' say fruitName color[ fruitName ] -- shows fruit name and color end |
-- store.roo store : class extends Map initialize : method say 'The store is ready.' return '' remember : method select when arg() = 2 then do -- ADD an association v = ^ add( arg(1), arg(2) ) ^ save return v end when arg() = 1 then -- RECALL association return ^ getAt( arg(1) ) otherwise call raiseObjection 'STORE: 1 or 2 arguments are expected.' end forget : method v = ^ removeAt( arg(1) ) -- FORGET association ^ save return v listKeys : method keys = '' loop ix over ^ self keys = keys ix end return keys listAll : method return ^ toDelimitedString( '0d0a'x ) -- LIST associations save : method -- default 'save' method does nothing return ''
The following program is a simple interactive main program that uses the store class.
-- store.rooProgram store = ^^ persistentClipStore -- prepare the 'persistentClipStore' object call showUsage signal on halt do forever parse linein request +1 key '=' value key = strip( key ) value = strip( value ) select when request = '' then nop when request = '+' then store ~ remember( key, value ) when request = '?' then say store ~ remember( key ) when request = '-' then store ~ forget( key ) when request = 'k' then say store ~ listKeys when request = '!' then say store ~ listAll when translate( request ) = 'Q' then exit 0 otherwise call showUsage end end halt : exit 0 showUsage : procedure say 'Usage:' say ' + key = value -- adds a value' say ' ? key -- locates value associated with key' say ' - key -- forgets value associated with key' say ' k -- lists all keys' say ' ! -- lists all associations' say ' Q -- terminates' return
Here is an example session of the store program.
The store is ready.
Usage:
+ key = value -- adds a value
? key -- locates value associated with key
- key -- forgets value associated with key
k -- lists all keys
! -- lists all associations
Q -- terminates
+ address=box 1
+ city=eliot
+ state=me
+ zip=03903
? city
eliot
k
address city state zip
!
address=box 1
city=eliot
state=me
zip=03903
q
There are numerous
Descriptions are provided for the initialize method of each class. The initialize method is usually invoked during class construction. The class construction parameters are passed to the initialize method. The initialize method is only invoked directly by an explicitly derived class. The randomSequence example program explicitly invokes the initialize method of the vector class.
The following built-in classes are provided.
Aggregate | a generic collection base class |
BitVector | a condensed vector of boolean values of a fixed size -- 4096 bits |
Callback | abstract callback class associated with an external program |
CharacterVector | a vector of one-byte wide characters |
Clipboard | a clipboard text encapsulation |
Comparator | abstract class for comparing two items |
Console | console stream |
ContextVector (aka StackTrace) |
system call vector access class |
DriveContext (aka Disk, DiskContext, Drive) |
drive (disk) reference context |
Emitter | an output stream emitter |
Exception | exception information that can be referenced by catch condition handlers |
ExternalClass | a class that is supported by an external program |
File | file information |
FolderContext (aka Directory, DirectoryContext, Folder) |
folder (directory) reference context |
InLineFile | an input file that is accessed as a sequence of lines |
InOutLineFile | a file that is updated as a sequence of lines |
InStream | default input stream (standard input) |
List | a collection of heterogeneous items. |
Map | a collection of heterogeneous items. a map is indexed by a string value |
Math | various mathematic functions (natural logarithm, sine, cosine, etc) and constants (π, e, Φ, γ) |
Object | a generic object base class |
OrderedVector | an ordered collection of items multiple items may have the same value |
OutLineFile | an output file that is accessed as a sequence of lines |
OutStream | default output stream (standard output) |
Pattern | a regular expression pattern |
PatternMatch | matching information for a regular expression pattern search |
Queue | a collection of heterogeneous items, that is accessed at the front or end. |
Set | an ordered collection of unique items |
Socket | a TCP/IP socket send/receive class |
Stack | a collection of heterogeneous items, that is accessed at the end. |
System | system information |
SystemPropertyMap | a collection of system properties (aka environment variables) a map is indexed by a string value |
Table | a two dimensional table containing an arbitrary number of rows, and a fixed number of columns |
Tree | a hierarchical object |
Vector | a collection of heterogeneous items. |
WideCharacterVector | a vector of two-byte wide characters |
The following table uses indentation to indicate built-in class derivation structure. Methods in a base class can be used in a derived class.
Object | a generic object base class |
.. Aggregate | a generic collection base class |
.... List | a collection of heterogeneous items. |
...... InOutLineFile | a file that is updated as a sequence of lines |
...... Queue | a collection of heterogeneous items, that is accessed at the front or end. |
.... Map | a collection of heterogeneous items. a map is indexed by a string value |
...... SystemPropertyMap | a collection of system properties (aka environment variables) a map is indexed by a string value |
.... OrderedVector | an ordered collection of items multiple items may have the same value |
.... Vector | a collection of heterogeneous items. |
...... ContextVector (aka StackTrace) |
system call vector access class |
...... InLineFile | an input file that is accessed as a sequence of lines |
...... OutLineFile | an output file that is accessed as a sequence of lines |
...... Stack | a collection of heterogeneous items, that is accessed at the end. |
.......... DriveContext (aka DiskContext) |
drive (disk) reference context |
.......... FolderContext (aka DirectoryContext) |
folder (directory) reference context |
.... Set | an ordered collection of unique items |
.. BitVector | a condensed vector of boolean values of a fixed size -- 4096 bits |
.. Callback | abstract callback class associated with an external program |
.. CharacterVector | a vector of one-byte wide characters |
.. Clipboard | a clipboard text encapsulation |
.. Comparator | abstract class for comparing two items |
.. Math | various mathematic functions (sine, cosine, etc) and constants (π, e, Φ, γ) |
.. Pattern | a regular expression pattern |
.. PatternMatch | matching information for a regular expression pattern search |
.. Emitter | an output stream emitter |
.... Console | console stream |
.... OutStream | default output stream (standard output) |
.. Exception | exception information that can be referenced by catch condition handlers |
.. ExternalClass | a class that is supported by an external program |
.. File | file information |
.. InStream | default input stream (standard input) |
.. System | system information |
.. Table | a two dimensional table containing an arbitrary number of rows, and a fixed number of columns |
.. Tree | a hierarchical object |
.. WideCharacterVector | a vector of two-byte wide characters |
Socket | a TCP/IP socket client send/receive class |
Numerous classes are aggregates that store an arbitrary number of other items. Each item is a Rexx value or an instance of another object.
A common set of methods are used within these classes. The methods, that are available for each aggregate class, are listed in their class description.
Observe: aggregate references often involve index values. The Rexx language consistently indexes arguments and string positions with an origin of 1. Consequently, within aggregate methods an index value of 1 references the first item stored in the aggregate. The index must be in the range 1 through size(), inclusive.
Warning: an objection condition is raised when an index is specified that is not within the aggregate's bounds.
add( [ item [ , item [, ... ] ] ) | adds zero or more items, at the end. returns instance reference. |
addAggregate( aggregateInstance ) | adds all items from another aggregate, at the end. the size() and getAt() methods of the other aggregate are used to acquire items. returns instance reference. |
addDelimitedString( string, delimitingValue ) | adds items within a delimited value string, at the end. if either string is empty nothing is added. if the delimiter is a comma, the string is treated as a comma-separated value string. if the delimiter is a newline character ('0a'x) a series of lines (1) is acquired. returns instance reference. |
addFirst( item ) | adds item in front of all others. returns instance reference. |
addStem( stem ) | adds stem collection, at the end. stem.0 is #items, stem.1 is first item, etc. returns instance reference. |
addSystemQueue() | adds items, and removes them, from the external data queue. items are added at the end. returns instance reference. |
average() | returns average of items. uses a toString call per item if necessary. all values must be numeric. |
contains( item ) | returns 1 if the aggregate contains item, and 0 otherwise |
copyAggregate( aggregateInstance ) | removes all items. adds all items from another aggregate. a different type of aggregate can be copied. returns instance reference. |
count( item ) | returns #items that strictly match item. |
exchange( index1, index2 ) | exchanges two item values. returns instance reference. |
exists( index ) | returns "1" if the indexed element is in the aggregate, and "0" otherwise. |
getAt( index ) | gets indexed item. |
find( item ) | returns index of item. an index of 0 indicates the item was not found. |
initialize( [ item, item, ... ] ) | prepares the aggregate instance, and optionally adds a series of items. |
insertAt( index, item ) | inserts item at index. returns new size. |
isEmpty() | returns 1 if the aggregate is empty, and 0 otherwise. |
isNonEmpty() | returns 1 if the aggregate contains some items, and 0 otherwise. |
max( [ 'Strict' ] ) | returns maximum value of items. uses a toString call per item if necessary. performs a standard non-strict comparison per item pair, unless the 'Strict' comparison option is specified. |
maxLength() | returns length of longest item. uses a toString call per item if necessary. |
mean() | same as average(). |
min( [ 'Strict' ] ) | returns minimum value of items. uses a toString call per item if necessary. performs a standard non-strict comparison per item pair, unless the 'Strict' comparison option is specified. |
minLength() | returns length of shortest item. uses a toString call per item if necessary. |
removeAt( index ) | removes indexed item. returns the item that was removed |
removeAll() | removes all items. returns instance reference. |
removeMultiple( index, length ) | removes multiple items. the length value indicates the number of items to remove. returns instance reference. |
resize( count ) | resets the number of items in the aggregate. returns instance reference. |
setAt( index, value ) | replaces indexed item and returns the prior value. If the aggregate is a map a new association is established, otherwise the indexed item must be present. If the index is one larger than the aggregate's size, the item is added at the end. |
size() | returns the number of aggregated items. |
sum() | returns sum of items. uses a toString call per item if necessary. all values must be numeric. |
standardDeviation() | returns standard deviation of items. uses a toString call per item if necessary. all values must be numeric. |
toDelimitedString( delimitingValue ) (aka join) |
prepares a delimited value string from items. uses a toString call per item. same as toString if the delimiting value is a comma. the delimiter can be the empty string ! |
toHtmlString( [ listGroupTag [, listElementTag ] ] ) | returns an HTML file segment string. the default listGroupTag is 'UL'. the default listElementTag is 'LI'. tags can include attributes. the first word of a tag is used in the end tag. uses a toHtmlString call per item. if the item does not have a toHtmlString method, then a toString method is used. |
toStem( stem ) | prepares stem collection -- stem.0 is number of items, stem.1 is first item, etc. uses a toString call per item. returns number of items -- same as stem.0 |
toString() | prepares comma separated value string from items. uses a toString call per item. |
toSystemQueue() | adds items to the external data queue. returns number of items. uses a toString call per item. |
toXmlString( [ listGroupTag [, listElementTag ] ] ) | returns an XML file segment string. the default listGroupTag is 'roo:list'. the default listElementTag is 'roo:listitem'. tags can include attributes. the first word of a tag is used in the end tag. uses a toXmlString call per item. if the item does not have a toXmlString method, then a toString method is used. returns a string of lines separated by newline characters ('0a'x) |
variance() | returns variance of items. uses a toString call per item if necessary. all values must be numeric. |
(1) lines can be separated by an isolated carriage return ('0d'x), an isolated line feed ('0a'x), or a combination of these in either order.
Observe: the various methods that start with 'add', as well as the copyAggregate and removeAll methods, return a string which is a reference to the current instance. This allows the result of the operation to be processed directly as follows:
say ^^ vector ~ add( 'abracadabra', 'shazam' ) ~ toString /* shows: abracadabra,shazam */ |
The BitVector class is excellent for storing a a condensed vector of boolean values of a fixed sizes. The extent can not exceed 4096 bits. The default extent is 128 bits. The active extent can be revised to a more convenient size by using the resize method. When more bits are required, you can make a vector of bitvectors. A substring of bits can be extracted by the getMultiple and getMultipleBytes methods. Similarly, a substring can be assigned by the setMultiple and setMultipleBytes methods. Bits can be accessed with square brackets. You can also process the bits with the LOOP .. OVER instruction.
Bits are indexed using the normal Rexx method. An index of 1 references the first bit location.
Hint: generally you will use a bit vector that is shorter than 4096 bits. In this case, don't forget to use the resize method, otherwise you will get surprises when the toString method is invoked.
allOff() | returns "1" if all bits are off, and "0" otherwise. |
allOn() | returns "1" if all bits are on, and "0" otherwise. |
and( otherBitVector ) | performs a bitwise AND of this bit vector with otherBitVector. returns instance reference. |
anyOn() | returns "1" if any bit is on, and "0" otherwise. |
count() | returns number of bits that are on. |
exclusiveOr( otherBitVector ) | performs a bitwise EXCLUSIVE-OR of this bit vector with otherBitVector. returns instance reference. |
flipAll() | flips all bits off. returns instance reference. |
flipAt( index ) | flips indexed bit on. returns the bit's new value. |
fromString( booleanString ) | prepares bits from boolean digits in booleanString -- e.g. "00101010". the number of bits that are assigned is limited by the length of the string. returns instance reference. |
getAt( index ) | gets indexed bit value -- "0" or "1" |
getMultiple( index, length ) | prepares boolean string from substring of bits -- e.g. "00101010" |
getMultipleBytes( index, length ) | prepares Rexx hexadecimal literal string from substring of bits -- e.g. '42 00 42 ...etc 'x |
initialize( [ booleanString ] ) | prepares bit vector, and optionally sets bits from boolean digits in booleanString -- e.g. "00101010" |
or( otherBitVector ) | performs a bitwise OR of this bit vector with otherBitVector. returns instance reference. |
resetAll() | resets all bits off. returns instance reference. |
resetAt( index ) | resets indexed bit. returns the bit's prior value. |
resize( newSize ) | alters the size of the bit vector. the maximum size is 1024. bits after the newSize are reset to zero. returns instance reference. |
setAll() | sets all bits off. returns instance reference. |
setAt( index [, booleanValue ] ) | sets indexed bit on. if booleanValue is specified, the bit is set to the value. returns the bit's prior value. |
setMultiple( index, booleanString ) | assigns substring of bits from boolean string -- e.g. "00101010". the number of bits that are assigned is limited by the length of the string. returns prior value boolean string. |
setMultipleBytes( index, byteString ) | assigns substring of bits from Rexx hexadecimal literal string -- e.g. '42 00 42 ...etc 'x. the number of bits that are assigned is limited by the length of the hexadecimal literal. returns prior value boolean string. |
size() | returns the current number of bits. which is 4096, or a smaller size established by the resize method. |
toByteString() | prepares Rexx hexadecimal literal string from bits -- e.g. '42 00 42 ...etc 'x. |
toString() | prepares boolean string from bits -- e.g. "00101010". |
The following shows various BitVector method uses. The quoted value in parentheses following the say keyword is the value of the expression to the right of the quoted value.
bv = ^^ bitvector say '(4096)' bv ~ size say '(8)' bv ~ resize( 8 ) ~ size say '(1)' bv ~ alloff say '(0)' bv ~ allon say '(0)' bv ~ anyon say '(0)' bv ~ count say '(1)' bv ~ flipAt( 8 ) say '(00000001)' bv ~ toString say '(0)' bv ~ alloff say '(0)' bv ~ allon say '(1)' bv ~ anyon say '(1)' bv ~ count say '(0)' bv ~ flipAt( 8 ) say '(11111111)' bv ~ flipAll ~ toString say '(0)' bv ~ alloff say '(1)' bv ~ allon say '(1)' bv ~ anyon say '(8)' bv ~ count say '(00000000)' bv ~ flipAll ~ toString say '(1)' bv ~ alloff say '(0)' bv ~ allon say '(0)' bv ~ anyon say '(0)' bv ~ count say '(11111111)' bv ~ setAll ~ toString say '(0)' bv ~ alloff say '(1)' bv ~ allon say '(1)' bv ~ anyon say '(8)' bv ~ count say '(00000000)' bv ~ resetAll ~ toString say '(0)' bv ~ setAt( 8 ) say '(1)' bv ~ getAt( 8 ) say '(1)' bv [ 8 ] -- square bracket indexing is supported say '(00000001)' bv ~ toString say '(01)' c2x( bv ~ toByteString ) say '(01)' bv ~ getMultiple( 7, 2 ) say '(01)' c2x( bv ~ getMultipleBytes( 1, 8 ) ) say '(1)' bv ~ setAt( 8 ) say '(1)' bv ~ resetAt( 8 ) bv[ 8 ] = '1' -- square bracket indexing is supported say '(1)' bv [ 8 ] -- square bracket indexing is supported say '(00000000)' bv ~ toString say '(0)' bv ~ setAt( 8 ) say '(00000000)' bv ~ resetAll ~ toString say '(00)' bv ~ setMultiple( 7, '11' ) say '(11)' bv ~ setMultiple( 7, '00' ) say '(00000000)' bv ~ setMultipleBytes( 1, '42'x ) say '(42)' c2x( bv ~ toBytestring ) say '(02)' c2x( bv ~ getMultipleBytes( 5, 4 ) ) bv1 = ^^ bitVector( '01010101' ) ~ resize( 8 ) bv2 = ^^ bitVector( '10101010' ) ~ resize( 8 ) say '(00000000)' bv1 ~ and( bv2 ) ~ tostring say '(01010101)' bv1 ~ fromString( '01010101' ) ~ toString -- reset bits say '(11111111)' bv1 ~ or( bv2 ) ~ tostring bv1 ~ fromString( '01010101' ) -- reset bits say '(11111111)' bv1 ~ exclusiveOr( bv2 ) ~ tostring say '(00000000)' bv1 ~ exclusiveOr( bv1 ) ~ tostring -- exclusiveOr self => all 0's bv1 ~ fromString( '10000010' ) say '(10000010)' bv1 ~ and( bv2 ) ~ tostring say '(10101010)' bv1 ~ or( bv2 ) ~ tostring |
The CharacterVector class is a vector of single byte values. A reduced set of the vector class methods are supported -- getAt, removeAt, removeAll, setAt, and size.
addString( value [, separatingValue ] ) | adds a Rexx value to the end of the character vector. the optional separatingValue is added to the end of the character vector, before adding the new value. the value, and the separatingValue, can be the empty string. returns instance reference. |
addWideCharacterVector( wideCharacterVector ) | adds characters from another wideCharacterVector instance. each value in the input vector is in host byte order. bytes are stored in the order -- highest first, then lowest. returns instance reference. |
addWideNetworkCharacterVector( wideCharacterVector ) | adds characters from another wideCharacterVector instance. each value in the input vector is in wide network byte order. wide network bytes are converted to wide host bytes, and then, bytes are stored in the order -- highest first, then lowest. returns instance reference. |
getAt( index ) | gets indexed character. |
initialize( [ initialValue ] ) | initializes vector with optional value. the value's toString method is invoked, if the value is an instance reference. |
insertAt( index, string ) | inserts characters in string at index. returns new size. |
insertWideAt( index, wideCharacterVectorInstance ) | inserts wide characters at index. two bytes are added to the character vector. bytes are inserted in the order -- highest first, then lowest. returns new size. |
removeAt( index ) | removes indexed character. returns the character that was removed. |
removeAll() | removes all characters. returns instance reference. |
removeMultiple( index, length ) | removes multiple characters. the length value indicates the number of characters to remove. returns instance reference. |
setAt( index, value ) | replaces indexed character(s) and returns the prior value. the size of the character vector can increase, if the index is one larger than. the current size, or if the value contains multiple characters which exceed. the size at the replaced position. |
size() | returns the number of aggregated characters. |
toString() | returns a string, which may include hexadecimal values. |
toWideCharacterVector() | exports contents to a new wideCharacterVector instance. |
toWideNetworkCharacterVector() | exports contents to a new wideCharacterVector instance, in network byte order. |
The Clipboard class is used to get text from the system clipboard, or to replace the clipboard text.
Note: some system environments do not have clipboards, so the use of this class may introduce portability difficulties.
getText() | gets clipboard text -- empty string if none is available. |
setText( text ) | assigns clipboard text. returns "1" if successful, and "0" otherwise. |
Some built-in classes use an optional comparator object to compare two items. A comparator object extends class comparator and must implement the isLess method as described below. When the comparator object is absent the Rexx less-than ( < ) operator is used instead. The Rexx less-than operator performs a numeric comparison when both items are numeric, otherwise a fixed case string comparison is performed.
This is an abstract description of the interfaces of an actual comparator class instance.
initialize() | initializes the instance |
isLess( item, item ) | compares two arguments; returns 1 when first is less, and 0 otherwise. |
Note: if either item (or both) being compared is a class instance, then it is up to the isLess method to convert the item to a comparable value. For example, the toString method of the item could be invoked to obtain a comparison value.
The console class is used to read and write characters or strings from or to the console.
emit() | sends text to destination. returns instance reference. |
hasInput() | returns 1 if input is available, and 0 otherwise. |
initialize() | initializes the instance |
println( [ line [, line, ... ] ] ) | (same as writeLine) |
readCharacters( n ) | reads specified number of characters from the console. |
readLine() | reads characters from the console until the Enter key is pressed. |
readln() | (same as readLine) |
writeCharacters( string ) | writes string to the console, without a trailing line terminator. returns number of characters that remain to be written (usually 0). |
writeLine( [ line [, line, ... ] ] ) | writes one or more lines to the console, ending each line with a line terminator. if no arguments are specified a single line terminator is written. returns number of lines that remain to be written (usually 0). |
The ContextVector class is used to analyze active method and procedure invocations. Each line contains the name of an active method or procedure, the associated source line, and a comma separated list of call arguments.
When method contexts are listed method names are preceded by the class name and a caret.
getAt( index ) | returns context information. |
initialize() | initializes the instance |
print() | prints context information to the console |
size() | returns number of contexts. |
Example of use:
cv = ^^ ContextVector do n=1 for cv ~ size say 'Execution context #'n '--' cv[ n ] end |
The DriveContext class establishes a drive as the current disk drive. When activated a DriveContext is similar to invoking a command that changes the active disk; i.e. A:
Observe: the drive context that was in effect prior to DriveContext instance creation is always restored, when the instance is removed.
A drive context has the same methods as a drive object.
initialize( [ driveLetter ] ) | prepares a drive context and sets driveLetter as the current drive, if it exists. if the driveLetter argument is absent, a context is established for the current file system drive. |
exists() | returns 1 if the drive exists, and 0 otherwise. |
getFolders() | returns a set of folder class instances. |
initialize( driveLetter ) | prepares to access drive information. |
toDetailedString() | returns the following space-separated values:. driveLetter driveType totalSpace freeSpace clusterSize activeDirectory. If disk space information is unavailable, then the totalSpace, freeSpace, and clusterSize values are all underscores. |
toString() | returns the drive name (i.e. C). |
Note: an irksome message box may be displayed when media is absent from a drive that supports mountable media -- i.e. floppy disks, CD-ROMs, etc. This message appears when either the exists, or toDetailedString methods are invoked.
The emitter class is used to write characters or strings to an arbitrary output stream. All emitter class derivatives should implement the methods listed below. This allows alternate emitters to be passed as parameters to procedures and methods. An example of a program that uses alternate emitters is qt.rooProgram.
emit() | sends text to destination. returns instance reference. |
initialize() | initializes the instance |
println( [ line [, line, ... ] ] ) | (same as writeLine) |
writeCharacters( string ) | writes string to the console, without a trailing line terminator. |
writeLine( [ line [, line, ... ] ] )() | writes one or more lines, ending each line with a line terminator. if no arguments are specified a single line terminator is written. returns number of lines that remain to be written (usually 0). |
Exception information that can be referenced by catch condition handlers
description() | prepares a printable string that describes the exception. |
initialize() | initializes the instance |
instruction() | identifies the instruction associated with the exception. |
name() | identifies the exception name. |
state() | identifies the state of the exception. |
toString() | prepares a printable string associated with the exception. this is a comma-separated combination of the above method results. in the order:. name,description,instruction,state |
An ExternalClass is a built-in class that invokes methods in an external program. In Windows system environments the program is a dynamic link library (DLL). An optional call back capability is also supported.
initialize( externalProgramName [, initializationArguments ] ) | instance initialization. loads externalProgramName, and invokes its optional 'initialize' method with the initializationArguments. |
perform( methodName, [ invocationArguments ] ) | invokes external class methodName. |
Note: the externalProgramName is automatically unloaded when all ExternalClass instance usages become inactive. The optional 'terminate' method of the external program is performed before unloading the program.
Note: the external program can call back to methods in a class that extends an ExternalClass instance. The WinList.rooProgram example, and WinList.roo class, illustrate the usage of ExternalClass with a program named WinList.dll.
The following diagram illustrates the components that are used in the WINLIST example.
![]() |
The external module can optionally provide an entry point named 'SetCallback'.
When this entry is present, its is invoked during instance initiation, with
an instanceContextLocator argument. This allows the external module to callback to the
The File class is used to obtain information about a specific file
For some of the following methods the example file name is:
c:\roo\aProgram.rooProgram |
initialize( filename ) | file to analyze. The file name can be partially qualified. It is retained as a fully qualified name at the time of initialization. |
exists() | returns 1 if the file exists, and 0 otherwise. |
getDirectoryPath() | returns the directory containing the file name. for the example file name, the directory name is: c:\roo. Note: if the file being analyzed is a directory, getDirectoryPath returns the parent directory path that contains the directory. |
getExtension() | returns the final file name segment. for the example file name, the extension is: rooProgram. |
getFullPathName() | returns the complete file system name of the file (or directory). for the example file name, the full path name is: c:\roo\aProgram.rooProgram. |
getName() | returns the file name segment that follows the directory path, and precedes the extension. for the example file name, the name is: aProgram. |
getNameAndExtension() | returns the file name and extension that follows the directory path. for the example file name, the name and extension value is: aProgram.rooProgram. |
initialize( filename ) | file to analyze. The file name can be partially qualified. It is retained as a fully qualified name at the time of initialization. |
isDirectory() | returns 1 if the filename is a directory, and 0 otherwise. |
isFile() | returns 1 if the filename is a file (not a directory), and 0 otherwise. |
isReadonly() | returns 1 if the file is NOT writeable, and 0 otherwise. |
isWriteable() | returns 1 if the file IS writeable, and 0 otherwise. |
toDetailedString() | returns the following space-separated values:. fileModificationDateAndTime dirOrSize accessability. the fileModificationDateAndTime value is formatted as YYYY/MM/DD-HH:MM:SS. the dirOrSize value is 'DIR' if the file is a directory, otherwise it is the number of characters withinin the file. accessability is 'RO' if the file is read-only, and 'RW' if the file is writeable. |
toString() | returns the file name -- same as getFullPathName(). |
The FolderContext class establishes a folder as the current folder for subsequent file. system activity. When activated a FolderContext is similar to invoking a CHDIR command.
Observe: the folder context that was in effect prior to FolderContext instance creation is always restored, when the instance is removed.
initialize( [ folderPath ] ) | prepares a folder context and sets folderPath as the current folder, if it exists. if the folderPath argument is absent, a context is established for the current file system folder. |
exists() | returns 1 if the folder exists, and 0 otherwise. |
getFiles( [ filePattern ] ) | returns a set of file class instances, one per file that matches the filePattern. The default pattern is: "*.*". |
getSubFolders() | returns a set of folderContext class instances. |
initialize( folderPath ) | prepares to access folder information. |
toDetailedString() | returns the following space-separated values:. a fileModificationDateAndTime value, formatted as YYYY/MM/DD-HH:MM:SS. |
toString() | returns the folder name (i.e. C:\ROO). |
The InLineFile class is a line-oriented encapsulation of Rexx input/output stream capabilities. When the class is initialized all lines are loaded, and the file is closed. Subsequently, the InLineFile instance can be accessed by any of the Vector class methods, that do not alter line contents.
Observe: a NOTREADY condition is signalled, if enabled, when an attempt is made to read more than the number of available lines.
initialize( [ streamName [, 'NoPromptIfAbsent' ] ] ) | loads the stream. when streamName is the empty string, or absent, the default input or output stream is used. a prompt is displayed if the file does not exist, and the 'NoPromptIfAbsent' option is not specified. |
locate( line# ) | establishes a line reading position. line# must be between 1 and the number of lines in the file. returns "1" if successful, and "0" otherwise. |
readLine() | reads a line. |
readln() | (same as readLine). |
Hint: the file is closed when all instances are no longer active. Often you can accomplish this by dropping the variable that has the file instance value. For example:
fil = ^^ InLineFile( 'yourFile' ) drop fil -- this closes the file |
The InOutLineFile class is a line-oriented encapsulation of Rexx input/output stream capabilities. The class is intended to revise an existing file. When the class is initialized all lines are loaded. Subsequently, the InOutLineFile instance can be accessed by any of the List class methods. When all instance uses are inactive lines are flushed to the external file associated with the stream, and the stream is closed.
The InOutLineFile class is intended for general file alterations; i.e. deletions and insertions. The related InLineFile and OutLineFile are more appropriate for sequential file access.
Separate line positions are maintained for reading and writing.
Observe: a NOTREADY condition is signalled, if enabled, when an attempt is made to read more than the number of available lines.
initialize( [ streamName [, 'NoPromptIfAbsent' ] ] ) | loads the stream. when streamName is the empty string, or absent, the default input or output stream is used. a prompt is displayed if the file does not exist, and the 'NoPromptIfAbsent' option is not specified. |
emit() | updates the external file associated with the stream. returns instance reference. |
initialize( [ streamName [, 'NoPromptIfAbsent' ] ] ) | loads the stream. when streamName is the empty string, or absent, the default input or output stream is used. a prompt is displayed if the file does not exist, and the 'NoPromptIfAbsent' option is not specified. |
locateToRead( lineNumber ) | establishes lineNumber as the current read position. returns "1" if successful, and "0" otherwise. |
locateToWrite( lineNumber ) | establishes lineNumber as the current write position. returns "1" if successful, and "0" otherwise. |
permitWriteAtEnd( optionSetting ) | if optionSetting is 1, changes are written when all instances conclude. if optionSetting is 0, changes are discarded when all instances conclude. by default, changes are written when all instances conclude. returns instance reference. |
readLine() | reads a line from the current read position. |
readln() | (same as readLine). |
writeLine( [ line [, line, ... ] ] ) | writes one or more lines from the current write position. when the file is written, each line is concluded by a line terminator. if no arguments are specified a single line terminator is written. returns number of lines written. no lines are written if the file is read-only. |
println( [ line [, line, ... ] ] ) | (same as writeLine) |
Hint: the file is closed when all instances are no longer active. Often you can accomplish this by dropping the variable that has the file instance value. For example:
fil = ^^ InOutLineFile( 'yourFile' ) fil ~ writeLine( '...' ) drop fil -- this writes file lines and closes the file |
The outstream class is used to read characters or strings from the default input stream (standard input).
hasInput() | returns 1 if input is available, and 0 otherwise. |
initialize() | initializes the instance |
readCharacters( n ) | reads specified number of characters. |
readLine() | reads characters until the Enter key is pressed. |
readln() | (same as readLine) |
The List class is excellent for storing an arbitrary collection of heterogeneous objects. The performance of getAt and setAt requests is worse than the corresponding vector class. Performance is better than the corresponding vector class when items are inserted or removed at the front or the middle of the list.
The list class supports all aggregate class methods.
initialize( [ item, item, ... ] ) | prepares the list instance, and optionally adds a series of items. |
The Map class is excellent for storing a keyed collection of heterogeneous items. Each item that is associated with a key can be a Rexx value or an instance reference. An optional comparator instance can be assigned to establish a custom ordering of items. When a comparator instance has not been assigned standard, non-strict, Rexx comparisons are used to establish the ordering. Thus, numeric values are in numeric order. String values are in collating order. When class instance values are encountered, their associated value is the result of their 'ToString' method. When the associated class lineage does not have a 'ToString' method, an implicit value is used which is the class name followed by the relative instance index -- i.e. SOMECLASS #3.
add( key, value ) | associates key and value. returns instance reference |
addMap( mapInstance ) | adds all associations from another map. returns instance reference. |
comparator( comparatorValue ) | if comparatorValue is "REVERSE" items are sorted in reverse collating order. if comparatorValue is "MIXED" items are sorted in case-insensitive collating order. otherwise comparatorValue is a custom comparison class instance. returns the ordered vector's instance reference. |
contains( key ) | returns 1 if the map contains key, and 0 otherwise. |
copyMap( mapInstance ) | removes all associations. adds all associations from another map. returns instance reference. |
getAt( key ) | gets item associated with key. |
getIndices() | returns a set instance that contains all of the keys in this association. this is used by the LOOP .. OVER instruction |
initialize() | prepares a map instance. |
isEmpty() | returns 1 if the map is empty, and 0 otherwise. |
isNonEmpty() | returns 1 if the map contains some keys, and 0 otherwise. |
removeAt( key ) | removes key. returns instance reference. |
removeAll() | removes all keys. returns instance reference. |
setAt( key, value ) | replaces value associated with key. returns the prior value, or the empty string if a value was not associated with key. |
size() | returns the number of map associations. |
toDelimitedString( delimitingValue ) (aka join) |
prepares a delimited value string from keys. an equal sign separates each key and value. uses a toString call per key value. same as toString if the delimiting value is a comma. the delimiter cannot be the empty string ! |
toHtmlString() | returns an HTML file segment string. the group begins with a 'DL' tag. each key is defined within a 'dt' tag. each value is defined within a 'dd' tag. uses a toHtmlString call per key value. if the item does not have a toHtmlString method, then a toString method is used. |
toHtmlTableString( [ mapTableOptions ] [ , [ mapKeyColumnHeading ] [ , mapValueColumnHeading ] ] ) | returns an HTML file table segment string. the default mapTableOptions is 'border=1'. the default mapKeyColumnHeading is 'Key'. the default mapValueColumnHeading is 'Value'. uses a toHtmlString call per value. if the value does not have a toHtmlString method, then a toString method is used. |
toStem( stem ) | prepares stem collection -- stem.0 is number of associations, stem.1.key is first key, stem.1.value is first value, etc. uses a toString call per key value. returns number of associations -- same as stem.0 |
toString() | prepares comma separated value string from associations. uses a toString call per key value. |
toSystemQueue() | adds associations as lines to the external data queue. an equal sign separates each key and value. uses a toString call per key value. returns number of associations. |
toXmlString( [ mapGroupTag ] [ , [ mapKeyTag ] [ , mapValueTag ] ] ) | returns an XML file segment string. the default mapGroupTag is 'roo:map'. the default mapKeyTag is 'roo:mapkey'. the default mapValueTag is 'roo:mapvalue'. tags can include attributes. the first word of a tag is used in the end tag. uses a toXmlString call per value. if the value does not have a toXmlString method, then a toString method is used. returns a string of lines separated by newline characters ('0a'x). |
The Math class provides various mathematic functions (sine, cosine, etc) and constants (π, e, Φ, γ)
Note: the arguments for the trigonometric methods, and associated results, are measured in radians, not degrees!
Warning: if an argument is outside the domain of a function the string 'undefined' is returned.
Note: additional mathematic functions -- Gamma(X), lnGamma(X), sinh, cosh, sinh-1, etc. -- can be found in the MathX.roo example program.
bernoulliNumber( N ) | returns the Nth Bernoulli number -- Bn( N ). Note: N must be a non-negative even number. The largest bernoulli number that is available is Bn( 60 ). |
e() | returns the natural number e 2.71828 18284 59045 23536 02874 71352 66249 77572 47093 69996 ... (up to NUMERIC DIGITS) |
gamma() | returns Euler's constant -- γ 0.57721 56649 01532 86061 |
phi() | returns the golden ratio, phi -- Φ 1.61803 39887 49898 84820 45868 34365 63811 77203 09180 |
pi() | returns PI -- π 3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37511 ... (up to NUMERIC DIGITS) |
factorial( n ) | returns the factorial of n which must be a non-negative whole number that does not exceed 20. Note: you can use factorial.rex for larger values of n. |
naturalLogarithm( n ) (aka ln) |
returns the naturalLogarithm of n. n must be greater than 0. |
naturalPower( n ) | returns the natural number e raised to the power n. |
power( a, n ) | returns the value of a raised to the power n. If n is not a whole number, then a must be non-negative. If a is negative, and n is not a whole number, a syntax error condition is raised. If a and n are both zero, a syntax error condition is raised. |
convertDegreesToRadians( nDegrees ) | converts #degrees to the corresponding #radians. Note: the nDegrees is internally converted to the domain 0° to 360°. |
convertRadiansToDegrees( nRadians ) | converts #radians to the corresponding #degrees. Note: the nRadians is internally converted to the domain 0 to 2 π. |
sine( nRadians ) (aka sin) |
returns the sine of the angle measured as nRadians. |
cosine( nRadians ) (aka cos) |
returns the cosine of the angle measured as nRadians. |
tangent( nRadians ) (aka tan) |
returns the tangent of the angle measured as nRadians. abs( nRadians ) must be less than π / 2 |
arcSine( sineValue ) (aka arc sin) |
returns the #radians of the angle which has sine sineValue. abs( sineValue ) must be less than 1 |
arcCosine( cosineValue ) (aka arccos) |
returns the #radians of the angle which has cosine cosineValue. abs( cosineValue ) must be less than 1 |
arcTangent( tangentValue ) (aka arctan) |
returns the #radians of the angle which has tangent tangentValue. |
Here is an example that shows how to compute the sine of π/4 (45°)
math = ^^ Math say math ~ sine( ( math ~ pi ) / 4 ) |
Even better, the following example shows how to compute the value of π to 1000 decimal places.
-- the following computes PI to 1000 decimal places !!! math = ^^ math numeric digits 1000 say 4 * ( 4 * ( math ~ arctangent( 1 / 5 ) ) - math ~ arctangent( 1 / 239 ) ) |
In 1706, a mathematician named John Machin discovered that:
π / 4 = 4 * arctan( 1/5 ) - arctan( 1 / 239 )
You can click here to discover how Machin derived this incredible formula:
All classes are implicitly derived from the Object class.
created() | returns date and time of instance creation -- format: YYYYMMDD-hhmmss. |
initialize() | initializes the instance |
isInstanceOfClass( className ) | returns 1 if this instance includes the className in its class lineage, and 0 otherwise. |
lineage() | returns a series of class name lines. the first name is the outermost derived class. the last name is the lowest base class. the class Object is not listed in the result. |
toHtmlString() | (same as toString when not overridden) |
toString() | prepares a printable string associated with the instance value, if possible. |
toXmlString() | (same as toString when not overridden) |
The OrderedVector class is a vector, with the distinction that all items are ordered. Multiple items can have the same value. An optional comparator instance can be assigned to establish a custom ordering of items. When a comparator instance has not been assigned standard, non-strict, Rexx comparisons are used to establish the ordering. Thus, numeric values are in numeric order. String values are in collating order. When class instance values are encountered, their associated value is the result of their 'ToString' method. When the associated class lineage does not have a 'ToString' method, an implicit value is used which is the class name followed by the relative instance index -- i.e. SOMECLASS #3.
add( [ item [ , item [, ... ] ] ) | adds zero or more items. returns instance reference. |
comparator( comparatorValue ) | if comparatorValue is "REVERSE" items are sorted in reverse collating order. if comparatorValue is "MIXED" items are sorted in case-insensitive collating order. otherwise comparatorValue is a custom comparison class instance. returns the ordered vector's instance reference. |
contains( item ) | returns 1 if the OrderedVector contains item, and 0 otherwise. |
count( item ) | returns #items that strictly match item. |
addAggregate( aggregateInstance ) | adds multiple values from another aggregate. returns instance reference. |
addDelimitedString( string, delimitingValue ) | adds items within a delimited value string. if either string is empty nothing is added. if the delimiter is a comma, the string is treated as a comma-separated value string. if the delimiter is a newline character ('0a'x) a series of lines* is acquired. returns instance reference. |
addStem( stem ) | adds stem collection -- stem.0 is #items, stem.1 is first item, etc. returns instance reference. |
addSystemQueue() | adds items, and removes them, from the external data queue. returns instance reference. |
getAt( index ) | gets indexed item. |
initialize( [ item [ , item [, ... ] ] ) | instance creation method. initializes contents with zero or more items. |
remove( item ) | removes specific item. returns new size. |
removeall( item ) | removes all items. returns new size. |
size() | returns the number of items |
toDelimitedString( delimitingValue ) (aka join) |
prepares a delimited value string from items. uses a toString call per item. same as toString if the delimiting value is a comma. the delimiter can be the empty string ! |
toHtmlString( [ listGroupTag [, listElementTag ] ] ) | returns an HTML file segment string. the default listGroupTag is 'UL'. the default listElementTag is 'LI'. tags can include attributes. the first word of a tag is used in the end tag. uses a toHtmlString call per item. if the item does not have a toHtmlString method, then a toString method is used. |
toStem( stem ) | prepares stem collection -- stem.0 is number of items, stem.1 is first item, etc. uses a toString call per item. returns number of items -- same as stem.0. |
toString() | prepares comma separated value string from items. uses a toString call per item. |
toSystemQueue() | adds items to the external data queue. returns number of items. uses a toString call per item. |
toXmlString( [ listGroupTag [, listElementTag ] ] ) | returns an XML file segment string. the default listGroupTag is 'roo:list'. the default listElementTag is 'roo:listitem'. tags can include attributes. the first word of a tag is used in the end tag. uses a toXmlString call per item. if the item does not have a toXmlString method, then a toString method is used. returns a string of lines separated by newline characters ('0a'x). |
Observe: the union, intersection, difference, and nonIntersection methods are unavailable for an OrderedVector. These capabilities can be used by adding a orderedVector aggregate to a set instance, as shown in the first line in the example below.
Here is an example that shows the creation of an OrderedVector, which is immediately converted to a set. Then, various set computations are performed.
u = ^^ set ~ addAggregate( ^^ orderedVector( 'a', 'b', 'd', 'b' ) ) v = ^^ set( 'a', 'c', 'd', 'c' ) say 'u:' u ~ toString say 'v:' v ~ toString say 'union( u, v ) :' u ~ union( v ) ~ toString /* the union is: a,b,c,d */ say 'intersection( u, v ) :' u ~ intersection( v ) ~ toString /* the intersection is: a,d */ say 'nonIntersection( u, v ) :' u ~ nonIntersection( v ) ~ toString /* non-intersection is: b,c */ say 'difference( u - v ) :' u ~ difference( v ) ~ toString /* difference( u - v ) is: b */ say 'difference( v - u ) :' v ~ difference( u ) ~ toString /* difference( v - u ) is: c */ |
Here is an example that shows how the lines of a file can be sorted by an OrderedVector.
ovec = ^^ orderedVector ovec ~ addAggregate( ^^ InLineFile( inFileName ) ) // note: LineFile has size and getAt methods ^^ OutLineFile( outFileName ) ~ addAggregate( ovec ) |
The first line above prepares an ordered vector. The second line reads inFileName, and adds the lines to the ordered vector. The final line adds the lines, which are now sorted, to the output file outFileName. The lines are written when the scope of the output LineFile instance concludes.
The above example could be programmed in one instruction as follows
^^ OutLineFile( outFileName ) ~ addAggregate( ^^ orderedVector ~ addAggregate( ^^ InLineFile( inFileName ) ) ) |
Here is an example that shows how the lines of a file can be sorted in reverse collating order.
ovec = ^^ orderedVector ~ comparator( "REVERSE" ) ovec ~ addAggregate( ^^ InLineFile( inFileName ) ) // note: LineFile has size and getAt methods ^^ OutLineFile( outFileName ) ~ addAggregate( ovec ) |
Here is an example that shows how the lines of a file can be sorted in a custom order.
ovec = ^^ orderedVector ~ comparator( ^^ customSort ) // see customSort.roo below ovec ~ addAggregate( ^^ InLineFile( inFileName ) ) // note: LineFile has size and getAt methods ^^ OutLineFile( outFileName ) ~ addAggregate( ovec ) |
Here is an example of a customSort class:
/* customSort.roo */ isLess : method parse arg s1, s2 return length( s1 ) < length( s2 ) /* sort lines from shortest to longest */ |
The OutLineFile class is a line-oriented encapsulation of Rexx input/output stream capabilities. The class is intended to prepare a new file, or completely replace an existing file. Subsequently, the OutLineFile instance can be accessed by any of the Vector class methods. When all instance uses are inactive lines are flushed to the external file associated with the stream, and the stream is closed.
The OutLineFile class is intended for sequential writing of lines to a file, rather than deletions and insertions. The related InOutLineFile is more efficient for deletions and insertions.
initialize( [ streamName [, 'NoPromptIfExists' ] ] ) | establishes stream access. when streamName is the empty string, or absent, the default input or output stream is used. a prompt is displayed if the file exists, and the 'NoPromptIfExists' option is not specified. |
emit() | updates the external file associated with the stream. returns instance reference. |
initialize( [ streamName [, 'NoPromptIfExists' ] ] ) | establishes stream access. when streamName is the empty string, or absent, the default input or output stream is used. a prompt is displayed if the file exists, and the 'NoPromptIfExists' option is not specified. |
locate( line# ) | establishes a line writing position. line# must be between 1 and one more than the number of lines in the file. returns "1" if successful, and "0" otherwise. |
permitWriteAtEnd( optionSetting ) | if optionSetting is 1, changes are written when all instances conclude. if optionSetting is 0, changes are discarded when all instances conclude. by default, changes are written when all instances conclude. returns instance reference. |
writeLine( [ line [, line, ... ] ] ) | writes one or more lines from the current write position. when the file is written, each line is concluded by a line terminator. if no arguments are specified a single line terminator is written. returns number of lines written. no lines are written if the file is read-only. |
println( [ line [, line, ... ] ] ) | (same as writeLine). |
Hint: the file is closed when all instances are no longer active. Often you can accomplish this by dropping the variable that has the file instance value. For example:
fil = ^^ OutLineFile( 'yourFile' ) fil ~ writeLine( '...' ) drop fil -- this writes file lines and closes the file |
The outstream class is used to write characters or strings to the default output stream (standard output).
emit() | sends text to destination. returns instance reference. |
initialize() | initializes the instance |
println( [ line [, line, ... ] ] ) | (same as writeLine) |
writeCharacters( string ) | writes string to the output stream, without a trailing line terminator. returns number of characters that remain to be written (usually 0). |
writeLine( [ line [, line, ... ] ] ) | writes one or more lines to the output stream, ending each line with a line terminator. if no arguments are specified a single line terminator is written. returns number of lines that remain to be written (usually 0). |
The Pattern class establishes a regular expression pattern, and extended string search capabilities.
initialize( regularExpressionString ) | establishes a regular expression pattern. |
search( textToSearch [, ['IgnoreCase'] [, startOffset ] [, 'SegmentsAlso' ] ] ) | searches string for matches of the regularExpressionString. the pattern search uses fixed-case comparisons, unless the 'IgnoreCase' option is specified. an optional startOffset can be specified. the default startOffset is 1, which proceeds from the beginning of the string. the 'SegmentsAlso' option also obtains segments that matched part of the regular expression. by default segments that match part of the regular expression are not obtained. returns a PatternMatch built-in class instance. |
toString() | returns regularExpressionString. |
Click here to review an example of a pattern match search, that also returns segments.
The PatternMatch class provides information describing matches that occurred during a regular expression pattern search. Instances of the PatternMatch class are created by the search method of the Pattern built-in class.
offset() | returns the position within the string that was searched where the match occurred. an offset of 0 indicates that a match did not occur. |
width() | returns the width of the string that matched the regular expression. |
segments() | returns a vector of PatternMatch instances, for regular expression segments that were matched. segments that matched part of the regular expression are only available if the search() request specified the 'SegmentsAlso' option. the size of the vector is 0, if the regular expression did not have any segments. segments are defined by outermost paired parentheses within the search pattern. the expression a(.*)b has one segment .*. the expression a(.*)b([0-9]+) has two segments -- .* and [0-9]+. the expression findThis has no segments. the expression A((a.*b){3})Z has one segment (a.*b){3}. |
toString() | returns the substring within the textToSearch argument, of the associated search method of the Pattern class, that was matched. |
The following is an example of a pattern match search, that also returns segments. There are 2 segments in the pattern. These are defined within the outermost level of paired parentheses. The segments are associated with the following portions of the pattern.
pattern = ^^ pattern( "(((1-)?([0-9]{3})-){1,2})([0-9]{4})" ) say pattern ~ tostring match = pattern ~ search( "phone:207-555-1212 .", , , 'SegmentsToo' ) say 'offset' match ~ offset',width' match ~ width', text' match ~ tostring say "phone:207-363-6060 ." segments = match ~ segments loop ix over segments say 'segment' ix'. , 'offset' segments[ ix ] ~ offset , 'width' segments[ ix ] ~ width , 'text' segments[ ix ] ~ tostring end |
The Queue class is excellent for storing an arbitrary collection of heterogeneous objects. These are normally accessed at the beginning or the end. Other methods of the list class are also available; such as: isEmpty, isNonEmpty, size, setAt, and toString.
initialize() | initializes the instance |
pushFirst( item ) | adds an item to the front. returns instance reference. |
pushLast( item ) | adds an item to the end. returns instance reference. |
first() | returns the first item. |
last() | returns the last item. |
pullFirst() | retrieves, and removes the first item. |
pullLast() | retrieves, and removes, the last item. |
The Set class is a Vector, with the distinction that all items are unique, and ordered. An optional comparator instance can be assigned to establish a custom ordering of items. When a comparator instance has not been assigned standard, non-strict, Rexx comparisons are used to establish the ordering. Thus, numeric values are in numeric order. String values are in collating order. When class instance values are encountered, their associated value is the result of their 'ToString' method. When the associated class lineage does not have a 'ToString' method, an implicit value is used which is the class name followed by the relative instance index -- i.e. SOMECLASS #3.
The set class supports all aggregate class methods, plus the following methods:
comparator( comparatorClassInstance ) | if comparatorValue is "REVERSE" items are sorted in reverse collating order. otherwise comparatorValue is a custom comparison class instance. returns the set's instance reference. |
contains( item ) | returns 1 if the set contains item, and 0 otherwise. |
difference( otherSet ) | returns instance that is a set difference; a set instance minus another set instance. |
intersection( otherSet ) | returns instance that is the intersection of a set instance with another set instance. |
initialize( [ item, item, ... ] ) | prepares the set instance, and optionally adds a series of items. |
nonIntersection( otherSet ) | returns instance that is the non-intersection of a set instance with another set instance. the non-intersection is the union of two sets minus their intersection. |
union( otherSet ) | returns instance that is the union of a set instance with another set instance. |
Observe: the union, intersection, difference, and nonIntersection methods compare one set instance versus another set instance, and return a new set class instance. If otherSet value is not a set instance, an OBJECTION condition is optionally raised. If the OBJECTION condition is not actively being trapped, the new instance that is returned will be empty.
Here is an example of the use of two sets.
u = ^^ set( 'a', 'b', 'd' ) v = ^^ set( 'a', 'c', 'd' ) say 'u:' u ~ toString say 'v:' v ~ toString say 'union( u, v ) :' u ~ union( v ) ~ toString /* the union is: a,b,c,d */ say 'intersection( u, v ) :' u ~ intersection( v ) ~ toString /* the intersection is: a,d */ say 'nonIntersection( u, v ) :' u ~ nonIntersection( v ) ~ toString /* non-intersection is: b,c */ say 'difference( u - v ) :' u ~ difference( v ) ~ toString /* difference( u - v ) is: b */ say 'difference( v - u ) :' v ~ difference( u ) ~ toString /* difference( v - u ) is: c */ |
Here is an example that shows how the set can be sorted in reverse collating order.
say ^^ set ~ comparator( "REVERSE" ) ~ addDelimitedString( 'a^b^c', '^' ) ~ toString /* shows: c,b,a */ |
Here is an example that shows how a set can be sorted in a custom order. The customSort class is defined below.
say ^^ set ~ comparator( ^^ customSort ) ~ addDelimitedString( 'a^bbb^cc', '^' ) ~ toString /* shows: a,cc,bbb */ |
Here is an example of a customSort class:
/* customSort.roo */ isLess : method parse arg s1, s2 return length( s1 ) < length( s2 ) /* sort lines from shortest to longest */ |
The Socket class provides TCP/IP socket capabilities. The class can be used for UDP datagram clients or servers, or TCP clients.
Note: the Socket class cannot be used to implement TCP servers.
bind( port ) | activates socket as a UDP server for the specified port. returns: instance reference. |
close() | deactivates the TCP/IP session. returns empty string. |
convert( hexlit, conversionType ) | converts a 2 or 4 byte hexadecimal literal to or from network byte order. conversionType is either ToNetwork or FromNetwork (only the first letter is significant). The width of hexlit MUST be either 2 or 4. Warning: REXX numeric values that are converted to characters are normally in network byte order ! So the results of D2C( 1432, 2 ) or D2C( 14321432, 4 ) are both in network byte order. |
getErrorCode() | gets error code associated with last request |
getHostIp( [ hostName ] ) | returns the IP address of the current host, or the host associated with hostName. |
getHostName( [ ipAddress ] ) | returns the name of the current host, or the host associated with ipAddress. |
hostInformation() | returns host information: format: ipAddress port type hostname type is either: TCP or UDP |
initialize( type [ , ipAddress, port ] ) | initializes a TCP/IP session for subsequent send and receive requests. type is one of: TCP or UDP. ipAddress is an internet IP address; such as, 216.239.41.99, or www.google.com. port is the number of the server's port. The ipAddress and port arguments should be unspecified for a UDP client. Initialization will not respond for a long time if the server is not accepting requests. |
receive( length ) | receives a response from the server. The length of the response may be less than the requested length. A receive request may not respond for a long time if the other address is not sending data. |
receiveFrom( length ) | receives a datagram response from another address. The length of the response may be less than the requested length. A receiveFrom request must be preceded by a bind request, if the program is acting as a server. A receiveFrom request may not respond for a long time if the other address is not sending data. Hint: the hostInformation method can be used to determine the address that sent the data. See the udpServer.rooProgram example. |
send( msg ) | sends a message to the server returns: number of bytes sent. The number of bytes sent may be less than the length of msg. |
sendTo( ipAddress, port, msg ) | sends a message to the server, as a UDP datagram ipAddress is an internet IP address; such as, 216.239.41.99, or www.google.com. port is the number of the server's port. returns: number of bytes sent. The number of bytes sent may be less than the length of msg. Note: after a receiveFrom request, a sendTo request will reply to the address that sent the message of the receiveFrom request. |
The Stack class is excellent for storing an arbitrary collection of heterogeneous objects. These are normally accessed at the beginning or the end. Other methods of the vector class are also available; such as: isEmpty, isNonEmpty, setAt, size, and toString.
initialize() | initializes the instance |
push( item ) | adds an item to the end. returns an instance reference. |
pull() aka pop | gets, and removes, last item pushed. |
top() | gets last item pushed. |
stk = ^^ stack( 'open sesame', 'abracadabra', 'shazam' ) do while stk ~ isNonEmpty say stk ~ pull end |
The System class is used to access the system name, and other system information.
getDrives() | returns a set of drive class instances. |
initialize() | initializes the instance |
toString() | returns the system name (i.e. FAST_PC). |
The SystemPropertyMap class is used to reference and revise system properties (aka environment variables).
The SystemPropertyMap class has the same methods as the map class. The following methods have additional considerations.
add( key, value ) | sets environment variable key to value. returns instance reference. |
initialize() | initializes the instance |
removeAt( key ) | removes environment variable key. returns instance reference. |
setAt( key, value ) | replaces environment variable key with the new value. returns the prior value, or the empty string if a value was not associated with key. |
The following shows how all environment variables can be displayed.
props = ^^ systemPropertyMap loop ix over props say ix props[ ix ] end |
You can prepare an HTML table containing all system properties as follows.
say ^^ systemPropertyMap ~ ToHtmlTableString |
Observe: the addMap and copyMap methods are supported, but have no effect when applied to a SystemPropertyMap instance. This avoids accidental, undesired revisions to system properties.
The Table class is a list of vectors. A set of column headings is defined when the table is constructed. Each list element is called a row. Each of the vectors in a row has a fixed number of items, which are called column values. The number of items in a row is the same as the number of column headings. Item values are Rexx values or instances of other objects. References to rows and columns are indexed. A request to 'getAt( 1, 1 )' retrieves the first column value in the first row.
The following diagram may help you understand the nature of a table.
![]() |
initialize( heading1 [ , heading2, ... ] ) | defines column heading names, and implicitly the number of columns per row. at least one heading name is required. |
addAggregate( aggregateInstance ) | adds row * from aggregate. returns instance reference. |
addDelimitedString( string, delimitingValue ) | adds a row *. each column value is a delimited value within string. if either string is empty nothing is added. if the delimiter is a comma, the string is treated as a comma-separated value string. if the delimiter is a newline character ('0a'x) a series of lines* is acquired. returns instance reference. |
addDelimitedStringAggregate( aggregate, delimitingValue ) | adds rows from aggregate. each element of the aggregate is a delimited string of column values *. each column value is a delimited value within the aggregate item string. if either string is empty nothing is added. if the delimiter is a comma, the string is treated as a comma-separated value string. if the delimiter is a newline character ('0a'x) a series of lines* is acquired. returns instance reference. |
addStem( stem ) | adds stem collection * -- stem.0 is #items, stem.1 is first item, etc. returns instance reference. |
addSystemQueue() | adds a row * of items, and removes them, from the external data queue. returns instance reference. |
columnContains( column, value [ , 'IgnoreCase' ] ) | returns '1' if column contains value, and '0' otherwise. a fixed case comparison is performed unless the 'IgnoreCase' option is specified. |
getAt( row ) | gets 'row' values -- a vector of values. |
getColumn( column ) | gets 'column' -- a vector of values. |
getHeading( index ) | returns indexed column heading. |
getHeadings() | returns a vector of column headings. |
getValue( row, column ) | gets a value. |
initialize( heading1 [ , heading2, ... ] ) | defines column heading names, and implicitly the number of columns per row. at least one heading name is required. |
insertAt( index, aggregate ) | inserts aggregate at index. returns new size. |
isEmpty() | returns 1 if the table is empty, and 0 otherwise. |
isNonEmpty() | returns 1 if the table contains some items, and 0 otherwise. |
removeAt( row [, length ] ) | removes one or more row(s). the optional length value indicates the number of rows to remove. returns vector of values in removed row. |
removeAll() | removes all rows. returns instance reference. |
resize( newSize ) | resets the number of rows. The newSize must not exceed the current number of rows. returns instance reference. |
rowContains( row, value [ , 'IgnoreCase' ] ) | returns '1' if row contains value, and '0' otherwise. a fixed case comparison is performed unless the 'IgnoreCase' option is specified. |
setAt( row, aggregate [ , 'KeepRemainingValues' ] ) | sets values in 'row' from an aggregate. If the KeepRemainingValues option is not specified, additional values are reset to the empty string. returns instance reference. |
setColumn( column, aggregate [ , 'KeepRemainingValues' ] ) | sets values in 'column' from an aggregate. If the KeepRemainingValues option is not specified, additional values are reset to the empty string. returns instance reference. |
setHeading( index, newCaption ) | alters indexed heading caption. the index must be between one and the width of the table, with the following exception. When there are no rows, the index can be one more than the table width. returns prior heading value. |
setHeadings( headingAggregate ) | sets headings from an aggregate of column headings. the number of headings is not altered by this method, with the following exception. When there are no rows, the number of headings is established by this method. returns instance reference. |
setValue( row, column, value ) | revises a value. returns prior value. |
size() | returns number of rows. |
toDelimitedString( delimitingValue ) (aka join) |
prepares a delimited value string from items. uses a toString call per row/column value. same as toString if the delimiting value is a comma. the delimiter can be the empty string ! |
toHtmlString( [ tableTagOptions ] ) | prepares HTML table segment. if tableTagOptions is absent, the default table tag options value is: "border=1". uses a toHtmlString call per value. if the value does not have a toHtmlString method, then a toString method is used. |
toStem( stem ) | prepares stem collection. stem.0 is number of values, stem.1.0 is number of values in first row, stem.1.1 is value in first row and first column, etc. uses a toString call per column value. returns number of rows -- same as stem.0. |
toString() | prepares a series of lines, one per row. each line is a comma separated value string. uses a toString call per value. |
toSystemQueue() | adds rows to the external data queue. uses a toString call per row. returns number of rows. |
toXmlString( [ tableTag ] [, [ tableHeadingsTag ] [, [ tableHeadingTag ] [ , rowTag ] ] ] ] ) | prepares XML file section. the default tableTag is: roo:table. the default tableHeadingsTag is: roo:tableHeadings. the default tableHeadingTag: is roo:tableHeading. the default rowTag is: roo:tableRow. uses a toXmlString call per value. if the value does not have a toXmlString method, then a toString method is used. |
width() | returns the number of columns. which is the number of headings specified for the table class construction request. |
(*) During an add operation, if there are fewer items than the column width, empty strings are added to the other columns. If there are more items in the aggregate, an OBJECTION condition is raised if it is enabled. Otherwise, the extraneous values are ignored.
The Tree class is an arbitrary hierarchical object element. It holds three items. A content item is the value associated with this hierarchical element. A child item locates an element that is subordinate to this element. A successor item locates an element that is a subsequent peer of this element.
The xmlTree program, and it's supporting class, is an excellent example of how the Tree class can be used to process XML information.
getContent() | returns the content associated with this element. |
getChild() | returns the child associated with this element. |
getSuccessor() | returns the successor associated with this element. |
hasChild() | returns '1' if a child is associated with this element, and '0' otherwise. |
hasContent() | returns '1' if content is associated with this element, and '0' otherwise. |
hasSuccessor() | returns '1' if a successor is associated with this element, and '0' otherwise. |
initialize( [ content ] [ , [ child ] [ , successor ] ] ) | initializes this element. |
setContent() | alters the content associated with this element. returns the prior content associated with this element. |
setChild() | alters the child associated with this element. returns the prior child associated with this element. |
setSuccessor() | alters the successor associated with this element. returns the prior successor associated with this element. |
toHtmlString( [ segmentTag ] [ , [ nodeTag ] [ , childTag ] ]) | returns an HTML file segment string. the default segmentTag is 'UL'. the default nodeTag is 'P'. the default childTag is 'LI'. tags can include attributes. the first word of a tag is used in the end tag. uses a toHtmlString call per item. if the item does not have a toHtmlString method, then a toString method is used. |
toString() | prepares comma separated value string from associations. uses a toString call per key value. |
toXmlString( [ segmentTag ] [ , [ nodeTag ] [ , childTag ] ] ) | returns an XML file segment string. the default segmentTag is 'roo:tree'. the default nodeTag is 'roo:treeNode'. the default childTag is 'roo:treeChild'. tags can include attributes. the first word of a tag is used in the end tag. uses a toXmlString call per value. if the value does not have a toXmlString method, then a toString method is used. returns a string of lines separated by newline characters ('0a'x). |
The Vector class is excellent for storing an arbitrary collection of heterogeneous objects. The performance of getAt and setAt requests is better than the corresponding list class. Performance is worse than the corresponding list class when items are inserted or removed at the front or the middle of the list.
The vector class supports all aggregate class methods.
initialize( [ item, item, ... ] ) | prepares the vector instance, and optionally adds a series of items. |
The WideCharacterVector class is a vector of two byte hexadecimal literals, in host byte order. It is particularly designed to be a vector of Unicode-16 character values. A reduced set of the vector class methods are supported -- getAt, removeAt, removeAll, setAt, and size.
addString( value [, separatingValue ] ) | adds a Rexx value to the end of the character vector. the optional separatingValue is added to the end of the character vector, before adding the new value. the value, and the separatingValue, are both treated as narrow character strings; both strings are widened. the value, and the separatingValue, can be the empty string. returns instance reference. |
addWideCharacterVector( wideCharacterVector ) | prepares items from another wideCharacterVector instance. each value in the input vector is in host byte order. returns instance reference. |
addWideNetworkCharacterVector( wideCharacterVector ) | prepares items from another wideCharacterVector instance. each value in the input vector is in network byte order. returns instance reference. |
getAt( index ) | gets indexed item. |
initialize() | initializes the instance |
insertAt( index, string ) | inserts characters in string at index. returns new size. |
insertWideAt( index, wideCharacterVectorInstance ) | inserts wide characters at index. returns new size. |
removeAt( index ) | removes indexed item. returns the item that was removed. |
removeAll() | removes all items. returns instance reference. |
removeMultiple( index, length ) | removes multiple items. the length value indicates the number of items to remove. returns instance reference. |
setAt( index, value ) | replaces indexed item and returns the prior value. the value must be one or two bytes long. if the value is one byte long, it is widened to two bytes. if the value is two bytes long, it is treated as a wide character. if the index is one larger than the aggregate's size, the item is added at the end. |
size() | returns the number of aggregated items. |
toNarrowString() | prepares a string that is as long as the vector size. only the lowest byte in each item value is written to the output string. information is lost if the highest byte of an item was non-zero. |
toString() | prepares a string that is twice as long as the vector size. bytes are stored in network byte order -- highest first, then lowest. |
toWideNetworkCharacterVector() | exports contents to a new characterVector instance, in network byte order. |