Virtual OS/2 International Consumer Education
VOICE Home Page:
May 2004

Newsletter Index
< Previous Page | Next Page >
Feature Index

Letters, Addenda, Errata

If you have any comments regarding articles or tips in this or any previous issue of the VOICE Newsletter, please send them to We are always interested in what our readers have to say.

April 24, 2004 - Only one letter this month but it's an in-depth comment from Chris Wohlgemuth regarding Thomas Klein's article Dr.Dialog, or: How I learned to stop worrying and love REXX - part 12.

The first thing I noticed is in the description of the DATE() function:

Note that you only need to specify the first character of the option and that it's not case-sensitive (thus, you can use 'Sorted', 'S', 's', 'sORted', etc.). In addition, you don't need to enclose the option string in quotes.

While this is accurate, it's worth mentioning that not quoting the option only works by accident because of a language feature of REXX. Any variable not explicitly given a value automatically has the variable name (in uppercase) as its value when referenced.

For example this script:

/* -- Sample script -- */

SAY " First: " || hello
hello = "Good bye!"
SAY "Second: " ||  hello
SAY " Third: " || "hello"

/* -- End of sample -- */


    First: HELLO
   Second: Good bye!
    Third: hello

Not enclosing the option string when using DATE() may result in obscure errors that are hard to find. Imagine a database application with some code like the following:

/* Sample: ACME special database sorter */

/* Sort my data using the month */
  rc = sort_my_Data_using_the_month_field()

/* Remember the last sort criteria */
sorted = "month"

/* Do something here */

/* Now try to get the current date suitable for sorting from REXX */
currentDate = DATE(sorted)

/* End of sample */

The last expression does not return the date in "YYYYMMDD" format but the current month!

The second thing I noticed is in the description of RxFuncAdd() where you find the following:

      result = RXFUNCADD(<my-funcname>, <dll-name>, <dll-funcname>)

The first parameter <my-funcname> tells REXX the name that you want to use for the function in your program (in your CALL to the function that's to say. In general you should use the same name as the <dll-funcname> to keep things clear. But at least note that you're free to use a different name for it. The drawback with it is that other programs don't know how you called that function and thus can't check if it was already loaded. Thus you should always use the <dll-funcname> in your <my-funcname> as well.

I disagree, esp. with the last sentence. While it's indeed common to have identical names for <dll-funcname> and <my-funcname>, it's not necessarily the right way to do it. It only works because most programmers don't drop the rexxutil functions after usage (and you really shouldn't do that, see below). REXX doesn't have a reference counter for external function so it's possible to drop any REXX function while it's still in use by another script. The following two scripts show that.

/* Drop funcs sample part 1 */
call RxFuncAdd 'SysTextscreensize', 'RexxUtil', 'SysTextscreensize'

SAY ""
SAY SysTextscreensize()
SAY SysTextScreenSize()

/* End of script */

/* Drop funcs sample part 2 */
call RxFuncAdd 'SysTextScreenSize', 'RexxUtil', 'SysTextScreenSize'

SAY "Loaded SysTextScreenSize"
SAY RxFuncDrop("SysTextScreenSize")
SAY "Dropped SysTextScreenSize"

/* End of script */

The first script just loads one function from the REXXUTIL.DLL to query the size of the screen (it may be necessary to have a recent fixpack for that function; it works at least with eCS 1.01), prints the info on the screen, and waits for a key. If you start the second script while script 1 is still waiting for a key, the function SysTextScreenSize() is dropped. After a keypress in the script 1 window the script continues to run but immediately fails while calling SysTextScreenSize() with a REX0043 error "Routine not found". This isn't a problem in general because authors usually don't drop any functions from the REXXUTIL DLL and you shouldn't do that either for the REXXUTIL DLL.

The <my-funcname> parameter avoids the problem (the RxFuncQuery() part of the article points out some other possible problems with it). If you load the function with a different name only known to your very own script, no other script may drop your function behind your back leading to runtime errors that are hard to find. This may be important if you use external function DLLs also used by other applications and those apps drop the used functions on termination to free system memory.

The parameter is also necessary if you have different REXX DLLs you have to use at the same time but using the same internal names. Normally REXX looks in the internal list of functions to see if a function is already available. If function foo() in bar.dll is already loaded, a request to use function foo() in newbar.dll fails even if the request is coming from a different application. External function DLLs available in different revision (for example the user control DLL for DrDialog) make things complicated because you may have two different applications needing different revisions of the DLL at the same time.

Conclusion is, loading and unloading of external functions may have some side effects you should be aware of. But don't be too concerned about that because in the vast majority of programs you don't have to bother. Get the INF file "Rexx Tips and Tricks" (on Hobbes) for more information.

Ok, after doing that much nitpicking ;-) I just want to say that this whole REXX series is a really great thing and I hope some more people start to write utilities using DrDialog. The package looks outdated on first sight but with a few little tricks you may create state of the art programs. A prominent example is for sure the Tame/2 scanner application which was created using DrDialog.

Feature Index
< Previous Page | Newsletter Index | Next Page >
VOICE Home Page: