Is REXX Better Than
Is REXX Better Than
Is REXX Better Than
Long answer: This question wastes a lot of bandwidth in comp.lang.rexx and other
newsgroups. Every language has its good points and its bad points. Some people
love REXX, some people hate it. Use a language that suits your needs.
Why does my OS/2 REXX program run more quickly the second time?
When you run a REXX CMD file for the first time, a tokenized version will be
stored on disk using the OS/2 extended file attributes. (You can see how big the
tokenized version is by using the /N option on the DIR command.) If a tokenized
version exists AND the file has not been modified, CMD.EXE will use the
tokenized version instead of parsing the source.
Note that there is a 64K limit on the size of an extended attribute entry, so very
large REXX programs do not benefit from this automatic tokenization.
REXX does not provide any support for returning more than a single value from a
function. If you wish to return multiple values you must devise an alternate
scheme. A simple solution is to concatenate the values together into a single string
and on return from the function use the PARSE instruction or the various string
functions to split the string back into its elements.
Don't forget that you can use non-printable characters (such as '01'x) to separate
the data -- REXX will correctly handle such strings. There may also be other
alternatives available to you if you are using an external function library that lets
you store data in separate memory pools or in disk files.
Here is one example of a way you can return multiple values from a routine and
extract them easily.
Call MyFunction
Parse Var result With v1 v2
v1 = X2C(v1)
v2 = X2C(v2)
Exit
MyFunction:
Return C2X(v1) C2X(v2)
Most versions of REXX (ARexx is an exception) use implicit file opening. That is,
each time you reference a file in a LINEIN, LINEOUT, CHARIN or CHAROUT
function, REXX will open the file for reading or writing if the file is not already
open. However, some operating systems, like DOS and OS/2, impose limits on the
number of files that can be open simultaneously, usually around 20 or so.
After the limit has been reached, any further attempts to open another file will fail.
That is why it is always good practice to close a file when you're done with it. In
OS/2 this is done using the STREAM function, as follows:
The STREAM function can also be used to open files, query their sizes and seek
into the file. Consult your REXX documentation for specific instructions for your
interpreter.
One of the features REXX lacks is a function to return a list of defined tails. There
are external libraries that provide functions to do so, but if that is not an option
then the only solution is to maintain your own list of tails in a string and use the
PARSE instruction or the WORDS function to traverse the list.
For OS/2, there are several sources of information. The most basic information is
found in the OS/2 Toolkit, which includes the REXXSAA.H header file and the
REXX Reference online document. The REXX Report includes a couple of articles
on the subject.
Sample source code comes with the OS/2 Toolkit and is also available
at rexx.uwaterloo.ca in the directory /pub/os2/vxrexx as VX-REXX Tech Notes #1
and #7 (vxtech01.zip, vxtech07.zip -- neither tech note requires that you own VX-
REXX).
a = 10
b = 20
call first
call second
call third
exit
first:
say "first -- a is" a "b is" b
return
second: procedure
say "second -- a is" a "b is" b
return
third: procedure expose a
say "third -- a is" a "b is" b b = 30
call first
return
first -- a is 10 b is 20
second -- a is A b is B
third -- a is 10 b is B
first -- a is 10 b is 30
One way to define and use global variables is to use a stem called "Globals." and
define all your procedures like this:
Then at the top of you program initialize the Globals stem and assign appropriate
values to your global variables
Globals. = ''
Globals.!NeedToSave = 0
Globals.!TmpDir = "D:\TMP"
The tail names in this example are all prefixed with '!', though you could also use
an underscore ('_'). This is just a convention used to avoid this kind of problem:
Globals.TmpDir = "D:\TMP"
call Foo
say Globals.TmpDir
exit
Foo: procedure expose Globals.
tmpdir = "foo"
Globals.TmpDir = tmpdir
return
It's a subtle bug that has to do with how REXX interprets stem tails.