VOICE Home Page: http://www.os2voice.org | May 2003 editor@os2voice.org

## DrDialog, or: How I learned to stop worrying and love REXX - Part 8

By Thomas Klein © May 2003

When I initially came up with the idea of this series, I wanted it to be suited for beginners - including beginners in REXX. Except for some minor parts, we only discussed objects and methods in DrDialog so far but did not actually start to do deal with REXX itself. Today, we'll put aside the "GUI stuff" and focus on an introduction to pure REXX on OS/2. Thus, if you're not a newby to REXX on OS/2, you're allowed to skip this issue ;)

### Where to start

In this part, we'll take a look at what's special with REXX regarding variables and some basic commands and functions. In order to avoid the necessity of writing scripts that contain just one or two lines to test REXX's behaviour, we will rely on a great tool to "play" with REXX. It's called `REXXTRY` and should be easily callable from command-line on your system. Just go ahead, open a command line session (an OS/2 window) and type `rexxtry`. If you happen to have Ulrich Moeller's XWorkplace installed along with the XCenter button, you could use the `Run...` menu option from it as well and simply enter `rexxtry` in there. In either case, you should be presented with something like this:

Fig.1: The rexxtry window

If `rexxtry` won't come up, you might need to check if it's installed in a directory that is part of the `PATH` variable defined in `config.sys`. Or - to put it another way - you might need to run it from within the directory it is installed in. Search for a file named `rexxtry.cmd`. By default, it resides in the `OS2` directory of your OS/2 installation drive.

`Rexxtry` can be used in several ways depending on how it was invoked. In our example, we just call it without any additional parameters which results in the "interactive mode" used to start from scratch and interpreting each input line from the user one by one.

To terminate the `rexxtry`-session, simply enter `exit`. By the way: As always, inputs are completed by pressing the `Enter` key...

### Say hello or "hello"...

To start with something special about REXX, we'll try to say hello by code, using the `say` command.

`say` is used to "write an expression to standard output". As we're using the interactive rexxtry tool with no special tricks, the "standard output" device in our case is the screen - thus, we're displaying stuff. But what about "expression"? Simply speaking, this can either be a literal (a string enclosed in quotes), a variable or a function. In the latter cases, the content of the variable or the value of the function will be displayed.

To start with something finally, let's say hello by entering

    say "hello"

This will result in a single output line of `hello` along with the dotted separator line provided by rexxtry (we'll ignore this one from now on).

What is so special in a funny way, is that REXX's interpreter is a very helpful guy. If you would write

    say hello

this would mean: Display the contents of the variable named `hello` - simply because there where no quotes around the string. Actually, one would expect an error message popping up, telling that there is no such variable defined. And actually, this is right. But... instead, REXX will evaluate it as an expression, and because there is no variable named `hello`, it takes it as it is and simply displays:

    HELLO

Oops! That's the special thing... of course, things are what they are supposed to be again, if we provide a variable named `hello`. First, enter

    hello = "Hi!"

then

    say hello

...and as expected, this will give us

    Hi!

Because now, there is a variable called `hello` and REXX displays its content (which is `Hi!`).

You might have used other programming languages before and you know that they differ in the way that simple output to the screen are formatted, especially when dealing with output that consist of literals and variables put together. REXX is no exception to that rule as it is quite "precise" in interpreting the expression "behind" the `say` keyword. Let's go on by entering the following lines:

    mol = 42
    say "The meaning of life is:" mol

This will show

    The meaning of life is: 42

You might wonder what is special about that... well, there is a space between the colon and the 42. Did we say to do so? I'm afraid we did - to make things clear, type

    say "The meaning of life is:"mol

This will give you

    The meaning of life is:42

And - by using a final example - using the command

    say "The meaning of life is:"
    mol

(with 7 spaces between the literal and the variable name) will result in an output of

    The meaning of life is:       42

The number of spaces used in the `say` command is exactly the same that is used in the output formatting, which is not typical for programming languages in general AFAIK. Usually, the command is parsed into a keyword and parameters part only and the number of spaces between them is ignored.

Now that we already know a way of doing outputs, let's look on a REXX command used for doing inputs. We'll use the `PULL` command to read user inputs. Actually, `PULL` is used to read a line from the "standard input" queue. Again, as we didn't mess with other ways of using queues up to now in our `rexxtry` session, this will make REXX wait for an input line from the user (terminated by the `return` key). Go on by entering:

    pull input

Rexxtry will now wait for your input. Just type any sentence that comes to your mind, but make sure it's using lower case letters (in parts at least). Then type

    say input

And you'll see that your input was turned uppercase. That's the way it is - if you want to get it back exactly as it was entered, you have to rely on another function named `PARSE` used in conjunction with `PULL` like in:

    parse pull input

Now

    say input

will give you exactly what you typed in. Of course, there's a lot more to mention about `PARSE` but we'll look into details of it in a later part.

Okay, so far we know basic input and output commands in REXX. Unfortunately, they won't be of use in DrDialog programs, as its environment doesn't allow the use of these functions - why should it on the other hand? In DrDialog we do displays by setting a control's text and doing inputs by retrieving an entry field's content. The `say` command can be very useful in DrDialog to check your programs behaviour as it can only display things in the run time monitor window. But both `say` and `pull` will allow you to do some basic REXX scripts outside DrDialog as well. Anyway: For now, we should get on by taking a look at elements of REXX that we'll deal with in DrDialog as well. Let's see how arithmetic operations are done in REXX.

### How to oneplusone

In REXX, most arithmetic operations are done by simply specifying a formula using the common notation of PLUS(+) and MINUS(-) signs, an ASTERISK(*) for multiplication and a SLASH(/) for divisions. As always, the common principles of algebra apply - that's to say, calculation is done from left to right with expressions in parenthesis being calculated first, as well as multiplication and division will precede any adding or subtracting operation. Some examples:

- Adding values
  `result = 12 + 4`
  `result` will contain 16
- Increasing a variable's value by 1
  `result = result + 1`
  The value of `result` will be increased by `1`
- Subtraction
  `result = a - 5`
  `Result` will contain the value of the variable `a` decreased by `5`
- Multiplication
  `cents = dollars * 100`
  `cents` will contain the value of the variable `dollars` multiplied by `100`
- Division
  `dollars = cents / 100`
  The same way back: The variable `dollars` will contain the value of the variable `cents` divided by `100`
- "Complex" function:
  `say 100 + 17 * (3 - 1)`
  This will display 134: The multiplications precedes the addition with the value in parentheses being calculated first...

Not that some of the examples above are taken from a kind of larger context: Increasing a variables value by 1 requires the variable to contain a numeric value prior to do the increase as it'll give you an error otherwise. The same applies to `result = a - 5`: The contents of `a` must be numeric prior to it. In `rexxtry` for example, you could do it like that:

    cents = 3456
    dollars = cents / 100
    say dollars

...which will display 34.56. Exponential calculation by the way is done by using double asterisks like in

    say "The maximum decimal value stored in a single byte is" 2 ** 8  -1

### Quotes and comments

Let's take a look at comments first. Comments are used to store information within a program source (or a script) that are not intended to be processed by the compiler or interpreter. They are used to comment certain parts of a program, in order to ease the understanding of the code. One thing is special about comments in REXX - that is, the first line of a REXX program must be a comment. I once read that this is used by OS/2 to distinguish between a REXX script and a batch command file, but I'm not sure if this is correct.

#### Test heading lower level

Anyway - take it as it is: A REXX script in OS/2 has to start with a comment. (In DrDialog however there is no need to do so, because the code you write will actually be embedded in a kind of code frame provided by DrDialog's environment.) A comment is initiated with the sequence /* (slash asterisk) and is terminated by the reverse notation */ (asterisk slash). Thus, a comment on a single line would look like that:

    /* this is a comment */

Comments can span multiple lines too - as an example, such comment would be something like...:

    /*
    the following routine is invoked each time a line was
    read from the input file. Each string within the line
    that matches the search criteria is removed. The rest
    of the line is then written to the output file. The
    number of strings found in the line is returned to
    the invoking routine by means of return code.
    */

If the comment spans various lines of code, it becomes quite difficult to distinguish comment from code at first sight. Thus, most often, you'll find large comments in REXX files done in another way - programmers rather prefer to use multiple lines of one-line-comments like...:

    /* the following routine is invoked each time a line was */
    /* read from the input file. Each string within the line */
    /* that matches the search criteria is removed. The rest */
    /* of the line is then written to the output file. The   */
    /* number of strings found in the line is returned to    */
    /* the invoking routine by means of return code.         */

The reason for programmers preferring this kind of commenting is its better readability: Such block of comments is more easily identified to be actual "comment" than multiple lines which have only ONE starting comment sequence and ONE ending sequence that might not be visible without prior scrolling down the code. Comments do not need to be the only part of a line. Quite often, you may want to just do a short comment for a single line of code and you're free to mix code and comment on a single line like in...:

    euros = marks / 1.95583  /* convert former 'german marks' to euros */

Now let's see if there is something to be mentioned about quotes. REXX does support both single and double quotes. Thus, the two following lines are equal in matters of output:

    say "hello"
    say 'hello'

The only thing you have to make sure is that quotes must match, otherwise REXX won't recognise them and will give you a "unmatched quote or *" error message... for example, if you would code a command like...:

    say 'hello"

The capability of REXX handling both types of quotes comes in handy if you want to display strings that actually contain quotes like...

    say "The file specified doesn't exist"

or

    say 'My boss said: "We need to re-focus on core competencies." '

But even provided with such great understanding by the interpreter, you might find yourself in a situation that requires you to use the same quotes in your string that you used to "put around" the string. In REXX this can be accomplished by doubling the quote (either single or double quote) inside the string. Hmm. Sounds difficult - here's an example:

    say 'Bruce Hornsby says: "That''s just the way it is." and he''s right.'

I would suggest you to play around with quotes in `rexxtry` to get an impression of how things work.

Date | Time | Description
--- | --- | ---
May
04. May 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
05. May 2003 | 8:00PM EDT (01:00 GMT) | General VOICE Meeting on IRC in #voice. All are welcome.
07. May 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
11. May 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
14. May 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
18. May 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
19. May 2003 | 8:00PM EDT (01:00 GMT) | General VOICE Meeting on IRC in #voice. All are welcome.
21. May 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
25. May 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
28. May 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
June
01. June 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
02. June 2003 | 8:00PM EDT (00:00 GMT) | General VOICE Meeting on IRC in #voice. All are welcome.
04. June 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
08. June 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
11. June 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
15. June 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
16. June 2003 | 8:00PM EDT (00:00 GMT) | General VOICE Meeting on IRC in #voice. All are welcome.
18. June 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
22. June 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
25. June 2003 | 10:00PM EDT (02:00 GMT) | The SCOUG Help Desk meets in #SCOUG on WEBBnet every Wednesday.
29. June 2003 | 3:00PM EDT (19:00 GMT) | The Warp Doctor team meets in #warpdoctor on WEBBnet every Sunday.
October
18. October 2003 | 8:00AM EDT (12:00 GMT) | Warpstock 2003 Weekend of October 18-19 in San Francisco, California. For more info see http://www.warpstock.org

### What's coming up next?

Well, that's it for today. Next month, we'll talk about conditional expressions (`if`, `select`), iterative structures (loops), subroutines and functions. Part 10 will deal with REXX'S wealth of string manipulating functions and some of the RexxUtil functions. Then, Part 11 will take us back to DrDialog-specific matters by digging into using multiple dialogs within a program. I'm not sure whether part 12 will start the sample application work or rather will cover things I forgot up to now... we'll see - stay tuned!

References:

GuiObjectREXX Yahoo! group: http://groups.yahoo.com/group/GuiObjectREXX/
News group for GUI programming with REXX: news://news.consultron.ca/jakesplace.warp.visualrexx
Download from Hobbes: http://hobbes.nmsu.edu/cgi-bin/h-search?key=drdialog&pushbutton=Search
IBM Redbook - "OS/2 REXX: Bark to Byte" http://publib-b.boulder.ibm.com/Redbooks.nsf/9445fa5b416f6e32852569ae006bb65f/50d91ba723b12cfa8525659d002a5793?OpenDocument&Highlight=0,rexx
Code sample - http://www.os2voice.org/VNL/past_issues/VNL0303H/cntsamp2_en.zip

Thomas Klein has been a contributor and member of our translation team for many a year.