Menu

VM/CMS GLOBALV in ooRexx

Help
m-stgt
2024-07-07
2024-08-05
  • m-stgt

    m-stgt - 2024-07-07

    Mark Miesfeld helped me a lot on my way from REXX to ooRexx. As a substitute of GLOBALV I could use .application~useGlobalConstDir('O') he advised, then.constDir[GLV_TTPOC] = pdelay would save a value and later -- in another scope -- it could be used like this: Call SysSleep .constDir[GLV_TTPOC] or similarly.

    In contrast, within a scope expose is sufficing for methods to access the associated object variable pool. Thus the a. m. "GLOBALV substitution" is only needed to interchange data among different scopes (class instances).

    In theory. In practice I find many cases in a program, where in several methods of class B setting a variable will be instantly available in a method of class A.

    Example:
    within method M1 of class A (running on a newly created thread) I initialize a stem and save it with .constDir[GLV_PRSTAT] = hlst.
    Within method M2 of class A I use following code to check the data interchange

    curva = hlst.1
    hlst. = .constDir[GLV_PRSTAT]
    say '<class A> hlst.1 =' hlst.1', was' curva
    

    With the assumption the clauses are executed in same sequence as the records are filed, curva will differ from hlst.1 iff it was altered in scope B.

    Within method initDialog of class B (subclass UserDialog) I use hlst. = .constDir[GLV_PRSTAT] to get the initial setting and expose to have it available where needed in scope B.

    In class B I have simple methods to get what user wants:

    ::method primo unguarded
    expose hlst.
    select
       when self~getRadioButtonData(302) then matrano = 2
       when self~getRadioButtonData(303) then matrano = 1
       otherwise matrano = 0
    end
    hlst.1 = d2x(64 * matrano + x2d(hlst.1) // 64, 2)
    .constDir[GLV_PRSTAT] = hlst.
    

    Here I do need to save hlst. so to get its value to scope A, while in following case the new value is instantly available also in scope A.

    ::method PROOP unguarded
    expose hlst.
    if self~getCheckBoxData(311) then do
       hlst.1 = c2x(bitand(x2c(hlst.1), 'F7'x))
       hlst.2 = c2x(bitor(x2c(hlst.2), '04'x))
    end
    else hlst.1 = c2x(bitor(x2c(hlst.1), '08'x))
    

    Questions:
    Is this phenomenon known? What circumstances require a save to constDir, when may it be omitted? Who is the "owner" of those "transborder" variables?

    Best,
    Mike

     
    • Erich

      Erich - 2024-07-08

      Hi Mike,
      once a reference to a mutable object like an Array or the hlst. Stem in
      your example is shared, any change to this shared object's content is
      visible in all shared places immediately (e. g. in the two methods of the
      two classes in your example). This is because you're just referencing the
      same object.

       
      • m-stgt

        m-stgt - 2024-07-08

        Hello Erich!

        Just few further questions:
        To establish a "trans-scope" reference it would be fully sufficient to execute once in method M1 of class A .constDir[GLV_PRSTAT] = hlst. and once in method initDialog of class B hlst. = .constDir[GLV_PRSTAT] no matter in which sequence?

        In subsequent program execution I'll never ever need to save altered content to .constDir[GLV_PRSTAT] nor do I have to get it from .constDir[GLV_PRSTAT]?

        Did it work that way also before ooRexx 5.oo?

        Must in all object variable pools the variable name be the same to make it shared?

        Best,
        M.

         
        • Rick McGuire

          Rick McGuire - 2024-07-08

          On Mon, Jul 8, 2024 at 9:06 AM m-stgt m-stgt@users.sourceforge.net wrote:

          Hello Erich!

          Just few further questions:
          To establish a "trans-scope" reference it would be fully sufficient to
          execute once in method M1 of class A .constDir[GLV_PRSTAT] = hlst. and
          once in method initDialog of class B hlst. = .constDir[GLV_PRSTAT] no
          matter in which sequence?

          No, the sequence must be first the assignment to the .constDir, then the
          assignment to the stem variable. All you are doing is passing references
          around, so it must be done in that order.

          In subsequent program execution I'll never ever need to save altered
          content to .constDir[GLV_PRSTAT] nor do I have to get it from
          .constDir[GLV_PRSTAT]?

          You shouldn't have to. Both places should be referencing the same container
          object already, so there's no need to make any update to the reference.

          Did it work that way also before ooRexx 5.oo?

          It's worked that way since 1990.

          Must in all object variable pools the variable name be the same to make it
          shared?

          No. The variable is just a holder for a reference to the object. There is
          no connection between the variables in the different context other than the
          fact that they hold references to the same object instance.

          Best,
          M.


          VM/CMS GLOBALV in ooRexx


          Sent from sourceforge.net because you indicated interest in <
          https://sourceforge.net/p/oorexx/discussion/408478/>

          To unsubscribe from further messages, please visit <
          https://sourceforge.net/auth/subscriptions/>

           
          • m-stgt

            m-stgt - 2024-07-08

            Hello Rick!

            TY for clarification.

            No, the sequence must be first the assignment to the .constDir, then the
            assignment to the stem variable. All you are doing is passing references
            around, so it must be done in that order.

            In that case, so to ensure this, it would be a good idea to set up all assignment to the .constDir in the main program before calling any methods.

            It's worked that way since 1990.

            Seems my approach to ooRexx was biased rather by know-how than know-why.

             
  • Rony G. Flatscher

    Maybe some background information on ooRexx (also working before ooRexx 5.0):
    - ooRexx like Rexx is a dynamic language, but much more so such that it maintains runtime information about all programs, using directories, one can be accessed by us using the environment symbol ".environment" (it contains all public ooRexx classes) and ".local" (it contains the local standard files named STDIN, STDOUT, STDERR and the ooRexx monitors that forward to them named INPUT, OUTPUT, ERROR
    - the interesting thing about the entries in these two directories is the following: each entry can be addressed using an environment symbol! E.g. if you want to access the directory class in .environment you could either write .environment~directory, or shorter: .directory; or if you are interested in saying something to the error monitor in .local, you could either write .local~error or .error; the reason is, that at runtime ooRexx will resolve any environment symbol (one that starts with a dot) by removing the first dot and then taking the remainder as the index being used for storing a value in .local or .environment. In effect ooRexx automatically will look up .local for the entry and if not found .environment, always in that order. If an entry was found, its value gets returned, otherwise the environment symbol (in uppercase) will be returned (a string)

    Access to .local or .environment is always possible in all parts of a program (prolog code, routine or method code), actually also from all programs that you may call from your program.

    If you want to couple different parts of your program you could use .local (preferred) or .environment to store and retrieve it. If you do, the ooRexx documentation suggests to use an index with a dot in it, as entries in .local and .environment without a dot are reserved by ooRexx.

    Here an example that exploits this knowledge:

    say "example of coupling all parts of a program via '.m.stg' ..."
       -- create a directory and store it with the index "M.STG" in .local
    .local~m.stg=.directory~new
    say ".local~m.stg:" .local~m.stg "or .local['M.STG']:" .local['M.STG'] "or shorter: .m.stg:" .m.stg
    say
    
    say "adding a stem array A. to .m.stg:"
    a.1="Stem's first entry!"
    a.0=1
    .m.stg~myStem=a.
    say "treating .m.stg~myStem as a collection, stem tail as index:"
    say ".m.stg~myStem[0]:" .m.stg~myStem[0] 'or .m.stg["MYSTEM"][0]:' .m.stg["MYSTEM"][0]
    say ".m.stg~myStem[1]:" .m.stg~myStem[1] 'or .m.stg["MYSTEM"][1]:' .m.stg["MYSTEM"][1]
    say
    
    say "treating .m.stg~myStem as a stem, using tails:"
    myTest. = .m.stg~myStem    -- get and assign stem to a stem variable
    -- stem variable myTest. refers the same stem object as stem variable a. above!
    
    say "myTest.0:" myTest.0 "myTest.1:" myTest.1
    say
    
    say "now calling routine 'hey' ..."
    call hey
    say
    
    say "invoking the class method 'HO_CLASS' ..."
    .myClz~ho_class
    say
    
    say "creating a myClz object and invoking its instance method 'HO_INSTANCE' ..."
    o=.myClz~new
    o~ho_instance
    say
    
    say "--- now let us see the content of the stem, using 'A.':"
    do i=1 to a.0
       say i":" a.i
    end
    say
    
    say "--- now let us see the content of the stem, using 'MYTEST..':"
    do i=1 to myTest.0
       say i":" myTest.i
    end
    say
    say "--- end of prolog code."
    
    
    ::routine hey
      say "1) routine 'HEY', fetching .m.stg~myStem as a stem"
      tsk. = .m.stg~myStem
      say "2) routine 'HEY', tsk.0="tsk.0 "tsk.1="tsk.1
      say "3) routine 'HEY', adding a new entry in stem array"
      i=tsk.0+1    -- get and increase item counter
      tsk.i = "routine 'HEY', added at" date() time()
      tsk.0 = i    -- adjust 0-tail to reflect new number of entries
    
    ::class myClz
    ::method ho_class class       -- class method
      say "1) method 'HO_CLASS', fetching .m.stg~myStem as a stem"
      tsk. = .m.stg~myStem
      say "2) method 'HO_CLASS', tsk.0="tsk.0 "tsk.1="tsk.1
      say "3) method 'HO_CLASS', adding a new entry in stem array"
      i=tsk.0+1    -- get and increase item counter
      tsk.i = "method 'HO_CLASS', added at" date() time()
      tsk.0 = i    -- adjust 0-tail to reflect new number of entries
    
    ::method ho_instance          -- instance method
      say "1) method 'HO_INSTANCE', fetching .m.stg~myStem as a stem"
      tsk. = .m.stg~myStem
      say "2) method 'HO_INSTANCE', tsk.0="tsk.0 "tsk.1="tsk.1
      say "3) method 'HO_INSTANCE', adding a new entry in stem array"
      i=tsk.0+1    -- get and increase item counter
      tsk.i = "method 'HO_INSTANCE', added at" date() time()
      tsk.0 = i    -- adjust 0-tail to reflect new number of entries
    
     
    • m-stgt

      m-stgt - 2024-07-08

      Hello Rony!

      TY for all those details and examples. It's some information overload at the moment, so it will take me a little while to grasp all aspects.

       
    • m-stgt

      m-stgt - 2024-07-09

      2nd reply -- hello Rony!

      I have run your example twice in single step mode (trace '?R'), got it now me think. With it you urged me to take a closer look to Chapter 6 "Rexx Runtime Objects" (why not "ooRexx Runtime Objects"?). Up to now I did shy away from all that smelled like... not like sulfur but too "oo-ish gizmo", I only dealed with the inevitable minimum like ooDialog.

      With your hint, and those from Erich and Rick, I will review my programs with a new perspective. Thank you.

      First finding: I may replace a call to whereisit: return sigl with .line
      Nice :)

      /M.

       
  • m-stgt

    m-stgt - 2024-08-04

    Once again, using stem in ooRexx like I would on VM/CMS, fails. Because I'm not fluent with the correct terms of those oo-ish components I can't report this error directly as a ticket, I may just show what happens.
    As suggested in this thread, I share variable's content within a scope by expose and for "trans-scope interchange" something like e.g. .constDir[GLV_PRSTAT] = hlst. in the leading program and corresponding hlst. = .constDir[GLV_PRSTAT] in subordinate routines. Works fine for me when altering single items of the stem.

    But not so for a "reset" of all stem items in one go. Executing hlst. = 0 in a subordinate scope seems to start a new object which is referenced by expose only, alas no more by .constDir. Therefore leading program and subordinate scope are "out of sync" (totally, cut-off in fact) in respect of this stem.

    It took me several hours to nail down this flaw, frankly, I regard it rather as a serious bug than just a nasty surprise.

     
    • Rick McGuire

      Rick McGuire - 2024-08-04

      On Sun, Aug 4, 2024 at 7:38 PM m-stgt m-stgt@users.sourceforge.net wrote:

      Once again, using stem in ooRexx like I would on VM/CMS, fails. Because
      I'm not fluent with the correct terms of those oo-ish components I can't
      report this error directly as a ticket, I may just show what happens.
      As suggested in this thread, I share variable's content within a scope by
      expose and for "trans-scope interchange" something like e.g.
      .constDir[GLV_PRSTAT] = hlst. in the leading program and corresponding
      hlst. = .constDir[GLV_PRSTAT] in subordinate routines. Works fine for me
      when altering single items of the stem.

      But not so for a "reset" of all stem items in one go. Executing hlst. = 0 in a subordinate scope seems to start a new object which is referenced
      by expose only, alas no more by .constDir. Therefore leading program
      and subordinate scope are "out of sync" (totally, cut-off in fact) in
      respect of this stem.

      It took me several hours to nail down this flaw, frankly, I regard it
      rather as a serious bug than just a nasty surprise.

      Nope, just a nasty surprise. When you do an assignment such as "hist. = 0",
      this creates a new fresh stem object and assigns it to the variable hist.
      This severs the link between hist. and any other stem variable since they
      no longer point to the same stem object.

      Rick


      VM/CMS GLOBALV in ooRexx


      Sent from sourceforge.net because you indicated interest in <
      https://sourceforge.net/p/oorexx/discussion/408478/>

      To unsubscribe from further messages, please visit <
      https://sourceforge.net/auth/subscriptions/>

       
      • m-stgt

        m-stgt - 2024-08-04

        Then, please, could you explain the fundamental difference between hlst. = 0 and hlst.5 = 0. And where it is documented.

         
        • Rick McGuire

          Rick McGuire - 2024-08-05

          hist. = 0 is an assignment to a stem variable. hist.5 = 0 is an assignment
          to a compound variable, which must adds/alters a an entry of the stem
          object reference by the stem variable. Stem assignment is documented in
          Section 1.13.4 Stem in the oorexx reference.

          Rick

          On Sun, Aug 4, 2024 at 7:58 PM m-stgt m-stgt@users.sourceforge.net wrote:

          Then, please, could you explain the fundamental difference between hlst. = 0 and hlst.5 = 0. And where it is documented.


          VM/CMS GLOBALV in ooRexx


          Sent from sourceforge.net because you indicated interest in <
          https://sourceforge.net/p/oorexx/discussion/408478/>

          To unsubscribe from further messages, please visit <
          https://sourceforge.net/auth/subscriptions/>

           
          • m-stgt

            m-stgt - 2024-08-05

            Ok, nice, TY.
            So the canonical "reset" would be nixbix. = 0; hlst. = nixbix. -- no, no betterment. Found it: hlst. = hlst.~empty (Not what I consider "upwardly compatible with classic REXX" to be, otherwise hlst. = 0 would work without creating a new object IMO.)

             

Log in to post a comment.