Rexx2Nrx.Rexx2RT.RexxSymb   ( vs 4.00, January 2003)

Introduction:

The class RexxSymb  is used to resolve references to the classic Rexx functions symbol and value. Whilst those functions have not been available in the original REXX implementation years ago, they nowadays are the important run-time routines to get access to a variable at run-time..

Early REXX implementations relyed on INTERPRET or external packages like GLOBALV  to do this, but since Personal REXX (from Quercus software) , and Mike Cowlishaws book The Rexx language (second edition) appeared, those two functions are part of the language. Hence, they are now available in the major number of Rexx implementations available.

Unfortunately, Mike left something open (the possible values of the SELECTOR),

 (the optional third argument in value) and this has led to numerous implementations of 'External' ,    'GLOBALV' ,'ENVIRONMENT','SYSTEM','OS2ENVIRONMENT','WINDOWS','WINxxx'' implementations of the same concept, which made actual REXX programs not so portable as desired

When Mike Cowlishaw would have SPECIFIED this part of the language, so many incompatibilities would have never arisen (´personal note from me, Thomas..Schneider@Donauland.at)´´´´

As a conclusion, you, should NEVER say a concept is 'implementation dependent'  when you want to keep a software portable ...

Going back to the routes, the funtionality of 'symbol' and 'value' is Rexx is as follows (examples/testval1.rexx):

/* textval1: simple symbol & value test */
xx=12345
say symbol('xx')
say symbol('yy')
xx=234
say 'new value of xx is:' value('xx')
call value 'xx',14
call value 'yy','abcdef' /* means setValue!*/
say 'new value of xx is:' value('xx')
say 'which must be also equal to:' xx
say 'yy has now value:' yy 'with value func:' value('yy')
say 'end of simple value test'
exit:

      translated to NetRexx, this program will look like (examples/testval1.nrx)

    import Rexx2Nrx.Rexx2RT.RexxSymb
    class testval1
    properties public static
    /* ... Declare Global Numbers */
    xx = int 12345
    /* ... Declare Global other Variables */
    yy = Rexx 'YY'
    method main(args=String[]) static
       arg=Rexx(args) -- program arguments as single string 
       arg=arg -- avoid NetRexx warning
       /* Attention: class: testval1 needs Symbolic interface RexxSymb) */
       RexxSymb.setClass('testval1')
       xx = 12345
       say RexxSymb.symbol('xx')
       say RexxSymb.symbol('yy')
       xx = 234
       say 'new value of xx is:' RexxSymb.getValue('xx')
       RexxSymb.setValue('xx',14) 
       RexxSymb.setValue('yy','abcdef')
       say 'new value of xx is:' RexxSymb.getValue('xx')
       say 'which must be also equal to:' xx
       say 'yy has now value:' yy 'with value func:' RexxSymb.getValue('yy')
       say 'end of simple value test'
       exit

     

    Rexx2Nrx will warn you when either symbol or value are used by your program as follows:

    Line 3: Attention: class: testval1 needs Symbolic interface (RexxSymb)

In summary, the following classic REXX rules apply:

1.) If a symbol  (for instance 'x'), is not yet defined, symbol('x') will return 'BAD'.

2.) value('x'), returns the current value of variable 'x', unless 'x' has not yet been assigned a value In the latter case value('x') returns 'X', as the default value of each undefined variable is it's uppercase name  in classic Rexx.

3.) The usage of 'value' with two arguments is aquivalent to a 'setValue' functionality. Note, however, that by definition in Mike Cowlishaws book, 'value('x', y) performs three actions, as follows:

    a) capture the old value of 'x' (for example, in y_old)

    b) set the value of the varibale with the name 'x' to y.

    c) when 'setValue' is invoked as a function, return the old value (namely y:old, as captured in step a)

I don't yet know why those decisions have been made, as it imposes a two-fold behaviour of the same function.

Anyway, in Rexx2Nrx,

- each reference to value('x')  is replaced by RexxSymb.getValue('x')

- each reference to call value('x',y)   is replaced by RexxSymb.setValue('x',y)

- and finally, each referennc to    z=value('x',y)  is replaced by

      z=RexxSymb.getValue('x')

      RexxSymb.setValue('x',y)

It might be, that 1 more line of code is involved, but I am definiteley sure that the purpose of the program part remains more readable and maintainable. getValue is used to obtain the current value, and setValue is used to change it - straightforward, I do believe.