New features in Object REXX that are useful in Classic REXX programs also

[Autolink] Menu

This section contains a list of some new features in Object-Oriented REXX that are useful even for Classic REXX programs.

Please do not forget to check the version of the REXX interpreter you're using with your REXX programs before you attempt to use on of these features!

---------- * ----------

DO i OVER stem

This is a very useful enhancement of DO loops. Now you can simply walk over all elements of a stem without knowing the tails:

 
                    /* drop all stem entries                         */
  drop myStem.

  do i = 1 to 40
    j = random( 400 )
    myStem.j = 1
  end /* do i = 1 to 40 */

  do i over myStem.
                    /* "i" contains the name of the next tail         */
                    /* (to get the value use "myStem.i")              */
    say 'The ' || i || ' was at least one time set'
    say 'The ' || myStem.i || ' was at least one time set'
  end /* do i over myStem */

---------- * ----------

Returning a stem variable

In Object-Oriented REXX a routine can return a stem variable. Example:

 
/* */
  test. = test1()

  do i = 1 to test.0
    say test.i
  end

return

test1:
                    /* init a local stem ...                          */
  a.0 = 3
  a.1 = 11
  a.2 = 22
  a.3 = 33
                    /* ... and return it to the calling routine.      */
return a.

---------- * ----------

Calculations and other stem variables are now possible to get or set a stem variable. Example:

 
/* init a stem with sample values                                     */
  do i = 1 to 500;
    test.i = i * 2
  end /* do */
  test.0 = 500

/* access the stem in the Classic way                                 */

  say test.5        /* (1)                                            */

  j = 4+55          /* (2)                                            */
  say test.j

  i = test.4        /* (3)                                            */
  say test.i

  i = test.4        /* (4)                                            */
  j = test.i
  say test.j

/* use the new way                                                    */

  say test.[5]      /* (1)                                            */

  say test.[4+55]   /* (2)                                            */

  say test.[test.4] /* (3)                                            */

                    /* (4)                                            */
  say test.[test.[test.4]]

---------- * ----------

PARSE [upper|lower|caseless]

The PARSE instruction now supports lower and caseless parsing.

---------- * ----------

Call-by-Reference-Parameters are now possible for internal and external REXX procedures (at least for stem variables):

 
/* */

  say
  say 'Sample code to show the usage of USE ARG in Object REXX '
  say

  j.0 = 2
  j.1 = 111
  j.2 = 222

  say 'Values of the variables before calling the sub routine:'
  say
  say '  j.0 is ' || j.0
  do k = 1 to j.0
    say '   j.' || k || ' is ' || j.k
  end /* do */

  say
  say 'Now calling TestUseArg ...'
  say
  call TestUseArg j.

  say
  say 'Values of the variables after calling the sub routine:'
  say
  say '  j.0 is ' || j.0
  do k = 1 to j.0
    say '   j.' || k || ' is ' || j.k
  end /* do */

exit

TestUseArg: PROCEDURE
  use arg local_j.

                    /* local_j points to the global stem j.           */
  local_j.0 = 3
  local_j.1 = '111 - one'
  local_j.2 = '222 - two'
  local_j.3 = '333 - three'

return

---------- * ----------

CALL now accepts variables that are evaluated before the CALL statement is executed:

 
/*                                                                    */

  myRoutine = 'MYTEST'
  call (myRoutine)
exit

MYTEST:
  say 'This is mytest!'
RETURN

Plese note that the contents of the variable must be in uppercase if calling an internal routine. This is not clearly stated in the online help.

---------- * ----------

DATE is not restricted to the current date any more. Now you can use the results of this function for date calculations (e.g. How many days are between day 1 and day 2?).

---------- * ----------

STREAM now supports some more commands and options; for example FLUSH, REPLACE (rewrite a file without doing a DEL first), and NOBUFFER. It also supports line-related positioning for files with fixed and variable length records. And there are now two different file pointers for every file -- one for reading from it and one for writing to it.

---------- * ----------

 TIME is not restricted to the current time any more. This allows calculations with time stamps.

---------- * ----------

Use the environment .local for variables global to the current process. Example:

 
/* create a variable global to the current process                    */
  .local['BS.MYVAR'] = 'This is a global variable'

/* call an external REXX routine to show that it works                */
  call rexxtry "say .local['BS.MYVAR'] "

  call rexxtry ".local['BS.MYVAR'] = 'This variable is set by REXXTRY'"

  say .local['BS.MYVAR']

/* you can also use the following code to read the variable           */
/* But be aware of the search order for environment symbols in        */
/* Object REXX!                                                       */
  say .BS.MYVAR

Note: "To avoid conflicts with future REXX-defined entries, it is recommented that entries you place in the program local environment or in the global environment include a least one period in the entry name."