Menu

#869 Packages should be able to block GlobalOptions requests

5.2.0
pending
None
complete
1
1 day ago
2025-12-14
Dom Wise
No

This is linked with the new Package class 'GlobalOptions' class method and the use case here is the rexxdebugger application though there may be others.

The new global option propagation mechanism is great when you want to debug programs made up of multiple files since you can set a global interactive trace option, even at the command line, to switch on interactive tracing for the main program and any programs it calls without needing to modify them but this also affects the debugger packages and these have limitations when it comes to tracing themselves - in particular having any interactive trace option active will flat out cause them to break

Something like the following (or an alternative) could be used by package code to lock a specific package level option so that it can't be overridden by GlobalOptions settings

::OPTIONS NOGLOBALOVERRIDE TRACE O

A GlobalOverride which attempts to violate this for a package should not cause an error.

I can see that GlobalOptions is a protected method but at least in the case where it is set from the command line this is redundant if there is nowhere to put code that will be called before packages are loaded to set a security manager. Even if a security manager can be set you don't gain much by doing this (at least for the problem that this ticket aims to solve) since it is a class method that doesn't care about any specific package

As part of the dynamic options enhancements the Package class 'options' instance method (also protected) has been added to change per-package options but I don't think anything has to be done with this because a package can set a security manager for this method while being loaded to limit how it can be used.

Discussion

1 2 > >> (Page 1 of 2)
  • Rony G. Flatscher

    Dom, enclosed please find a patch. Can you check it out whether it does what you desire and give feedback?
    ---rony

     
  • Dom Wise

    Dom Wise - 2025-12-18

    Thank you very much Rony. From a quick scan of the code it looks like a switch to be applied to all package options at once which works for me. It's possible a use case for more granular application of this option may exist (i.e. only block TRACE from being overridden instead of all options) but for me it's fine. I'm busy with Christmas preparations right now so will build and test it once I have some spare time, perphaps in a day or two.

     
    • Rony G. Flatscher

      Fine.
      One more thing: if you see a real need (especially in your ooRexx debugger), then could you supply a patch for individually ruling out global overrides for specific settings, such that we can discuss to add that instead. If it is not really needed at the moment, then I would prefer to leave it for a later release and start out with the general noglobaloverride patch.

       
  • Josep Maria Blasco

    Hmmm... Assume a situation like the one we had with ooRexxShell and TUTOR: one needs to propagate the NUMERIC settings. It would be a pity if NOGLOBALOVERRIDE forced the debugger to work with a different NUMERIC setting than the rest of the application. Since Dom's request is specifically about a problem with tracing, maybe what we would need is a NOTRACEOVERRIDE option instead?

     
    • jfaucher

      jfaucher - 2025-12-19

      On 19 Dec 2025, at 08:39, Josep Maria Blasco jmblasc2@users.sourceforge.net wrote:

      Hmmm... Assume a situation like the one we had with ooRexxShell and TUTOR: one needs to propagate the NUMERIC settings. It would be a pity if NOGLOBALOVERRIDE forced the debugger to work with a different NUMERIC setting than the rest of the application. Since Dom's request is specifically about a problem with tracing, maybe what we would need is a NOTRACEOVERRIDE option instead?

      IMO, the logic should be the same as ::options numeric inherit.
      No override by default.
      The package owner decides which global options he's accepting.

      Something like:
      ::options trace inherit -- to accept trace override

      I don't know if there are use cases to inherit the other options.
      Given the lack of common root for the errors and prolog, I assume that a new option name should be added (like "numeric" was added).
      That becomes complicated...

      Maybe we should come back at the original request [#858] "Add ability to override package options at runtime"
      and discuss about the use cases.

       

      Related

      Feature Requests: #858

      • Rony G. Flatscher

        There are at least two use cases that come to mind:
        * allowing a (like Dom Wise's great) debugger to offer the developer a fine graned control for debugging, but allowing to protect from overriding with global options for programs that may be negatively affected being put under the control of the program's author (hence the suggestions to use "PROTECT" as a new subkeyword)
        * changing e.g. the trace option globally for executing programs and their called/required programs in order to get a "complete trace log"

         
        • jfaucher

          jfaucher - 2025-12-19

          On 19 Dec 2025, at 14:56, Rony G. Flatscher orexx@users.sourceforge.net wrote:

          There are at least two use cases that come to mind:
          * allowing a (like Dom Wise's great) debugger to offer the developer a fine graned control for debugging, but allowing to protect from overriding with global options for programs that may be negatively affected being put under the control of the program's author (hence the suggestions to use "PROTECT" as a new subkeyword)
          * changing e.g. the trace option globally for executing programs and their called/required programs in order to get a "complete trace log"

          Is my understand correct?

          "numeric propagate" has been rejected because a 'push' of numeric settings impacted everyone, everywhere.
          It was decided to support a 'pull' of numeric options, with ::options numeric inherit.
          No impact on existing packages, each rexx coder is free to inherit or not the numeric settings.

          With your proposition, the 'push' of options is back, and each rexx coder will have to protect his packages.
          For example:
          rexx -og "::options numeric inherit"

          The above option contradicts the objective of not declaring “::options numeric inherit”.

           
          • Rony G. Flatscher

            There was a short discussion about pulling or pushing the "numeric inherit" setting and it has been the concensus to not push but to pull it, such that the author of a package was in control of the taking over of the numeric settings of the caller or not.

            So, the defaults will not push numeric settings, it is only available if the called package includes an "::options numeric inherit".

            Being able to change options - and in this way also being able to overrule "numeric inherit" - is only meant for situations, where it may make sense to test or check something.

            Probably the overruling ability will rarely be used at all. It may be the case that e.g. one wishes to check out and test what happens if one overrules "numeric inherit" temporarily.

            Anyone, who uses these options without knowing what he or she does probably does not know how to program in ooRexx as well. ;)

            Or with other words, these overruling options may not be used in deployed applications, but only for testing and debugging.

            The "PROTECT" idea (coming from Dom and Josep Maria) would allow the package creator to inhibit overruling settings. In this case one would use "::options numeric inherit protect numeric" and the overruling would not take place..

            But again, being able to dynamically change a package's options is not something that is to be expected to be done for a regular program. For a debugger or for special application the overruling ability might be necessary for debugging, testing or tracing.

             
            • jfaucher

              jfaucher - 2025-12-20

              On 19 Dec 2025, at 18:29, Rony G. Flatscher orexx@users.sourceforge.net wrote:

              The "PROTECT" idea (coming from Dom and Josep Maria) would allow the package creator to inhibit overruling settings. In this case one would use "::options numeric inherit protect numeric" and the overruling would not take place..

              I assume you meant
              ::options numeric noinherit protect numeric

              The last "numeric" is redundant, isn't it?
              Could be
              ::options numeric noinherit protect

              I find this latest declaration easy to read.
              This makes your message, in which you list 14 PROTECT <sub-options>, less frightening.
              It could be summarized to "an optional PROTECT at the end of any ::OPTIONS, right?
              ::options protect
              ::options trace o protect
              ::options numeric noinherit protect</sub-options>

              But again, being able to dynamically change a package's options is not something that is to be expected to be done for a regular program. For a debugger or for special application the overruling ability might be necessary for debugging, testing or tracing.

              I'm still not convinced by the push of options,
              because that forces the rexx coder to protect some ::options, if needed.

              The pull of options is not invasive.
              The rexx coder is protected by default.
              Currently, he can inherit the numeric settings.
              The INHERIT could be supported at the end of any ::OPTIONS.
              The declared option would be the default one, that the rexx coder accepts to be overriden.
              ::options inherit
              ::options trace o inherit
              ::options numeric inherit
              ::options novalue syntax inherit

               
              • Rony G. Flatscher

                Well, you mixed in two new features
                * using "protect" as a sub-subkeyword (where subkeyword is one of the options)
                * introducing "inherit" an all subkeywords (options) by allowing it as a sub-subkeyword

                Maybe stepping back a few steps and looking at this area, there are a few questions that can be posed:
                * for real world deployments would it be already sufficient to protect all options defining "NOGLOBALOVERRIDE" for a package?
                * is it really necessary to only protect individual options, and if so, what would be the best approach? Would the 'protect' idea be acceptable? if so, which version 'protect option' or using 'protect' as a trailing sub-subkeyword?
                * is it useful and desired to allow inheriting individual options beyond inheriting the numeric settings? What would be use cases?
                * Whatever proposal: how intuitive, how human-centric would a suggested proposal be? Would there be a risk of overwhelmed options directive statements that become illegible, incomprehensible (and thereby error-prone) at first look?

                Personally, I would think that only making "NOGLOBALOVERRIDE" (first suggestion by Dom) available would solve the problem Dom is currently facing with his debugger.

                It would still be possible to use the options method to change individual package options at runtime (for tools like the debugger, but also for developers).

                So suggesting "less is more" by only supporting NOGLOBALOVERRIDE which protects the package options, if a package developer thinks that there is a need for it.
                :)

                P.S.: Should it turn out that NOGLOBALOVERRIDE is not sufficient, we could always define new sub(sub)options at a later time.

                 
                • jfaucher

                  jfaucher - 2025-12-20

                  Thanks for your feedback Rony.
                  This will be my last message in favor of “pulling” rather than “pushing”; I think this email covers everything I wanted to share.
                  Personally, I don't need the push, but I don't mind to have it.
                  and I don't need the pull, except for numeric.

                  On 20 Dec 2025, at 14:30, Rony G. Flatscher orexx@users.sourceforge.net wrote:

                  Well, you mixed in two new features
                  * using "protect" as a sub-subkeyword (where subkeyword is one of the options)
                  * introducing "inherit" an all subkeywords (options) by allowing it as a sub-subkeyword

                  I didn't mix two new features.
                  I started from your example "::options numeric inherit protect numeric", and followed an argumentation to reach a proposition where either "protect" is used xor "inherit' is used, but not both.

                  Maybe stepping back a few steps and looking at this area, there are a few questions that can be posed:
                  * for real world deployments would it be already sufficient to protect all options defining "NOGLOBALOVERRIDE" for a package?

                  I don't need that.
                  But I understand it's needed by Dom because of the push.
                  If no push then no need of that.

                  • is it really necessary to only protect individual options, and if so, what would be the best approach? Would the 'protect' idea be acceptable? if so, which version 'protect option' or using 'protect' as a trailing sub-subkeyword?

                  I don't know.

                  • is it useful and desired to allow inheriting individual options beyond inheriting the numeric settings? What would be use cases?

                  I don't need that.

                  • Whatever proposal: how intuitive, how human-centric would a suggested proposal be? Would there be a risk of overwhelmed options directive statements that become illegible, incomprehensible (and thereby error-prone) at first look?

                  Yes, there is a risk. That was my feeling when reading you message where you listed 14 PROTECT <something></something>

                  Personally, I would think that only making "NOGLOBALOVERRIDE" (first suggestion by Dom) available would solve the problem Dom is currently facing with his debugger.

                  I would think that not pushing eliminates the problem Dom is currently facing.

                  It would still be possible to use the options method to change individual package options at runtime (for tools like the debugger, but also for developers).

                  So suggesting "less is more" by only supporting NOGLOBALOVERRIDE which protects the package options, if a package developer thinks that there is a need for it.
                  :)

                  I know an approach that is even simpler.

                  P.S.: Should it turn out that NOGLOBALOVERRIDE is not sufficient, we could always define new sub(sub)options at a later time.

                   
                  • Anonymous

                    Anonymous - 2025-12-20

                    jean Louis, I fear there is a misunderstanding. There would be no possibility to push the numeric settings! The only possibility is to not inherit (default) or to inherit the caller's numeric settings. A global override, if any, can only change inherit to noinherit or vice versa.
                    Maybe I miss something.

                     
                    • jfaucher

                      jfaucher - 2025-12-20

                      A global override, if any, can only change inherit to noinherit or vice versa.

                      That's the point! If I push "::options numeric inherit" then I can impose my own numeric settings.

                      # no problem
                      rexx main.rex 
                      
                      # no problem
                      rexx -o "::options numeric inherit" main.rex
                      
                      # Who broke my invariant?
                      rexx -og "::options numeric inherit" main.rex
                      

                      main.rex

                      ::options digits 4
                      ::requires "myPackageDigits2.cls"
                      

                      myPackageDigits2.cls

                      call check_invariant
                      
                      ::options digits 2
                      ::options numeric noinherit
                      
                      ::routine check_invariant
                         if digits() == 2 then
                             say "No problem"
                         else
                             say "Who broke my invariant?"
                      
                       
                      • Rony G. Flatscher

                        Ah, ok. You use "push" for global overriding. My understanding of "push" was that the caller would push his numeric settings on to a required/called program.

                        Your sample demonstrates, however, that it is possible to change the "numeric noinherit" setting to "numeric inherit" using "-og", having a non-desired effect on "myPackageDigits2.cls", which relies on no numeric setting inheritance.

                        Two remarks:
                        * if someone overrides the defined ::options using the global overriding feature and defining "::options numeric inherit", there must be a reason for doing so; by default (and so far) package options do not get changed
                        * if someone devices a package with an invariant depending on "digits 2", then with the "noGlobalOverride" the author can inhibit applying a global override on its package.

                        The latter, demonstrated with your set of programs, adding "::options noGlobalOverride" to myPackageDigits2.cls:

                        # no problem
                        rexx main.rex 
                        
                        # no problem
                        rexx -o "::options numeric inherit" main.rex
                        
                        # Who broke my invariant?
                        rexx -og "::options numeric inherit" main.rex
                        

                        main.rex

                        ::options digits 4
                        ::requires "myPackageDigits2.cls"
                        

                        myPackageDigits2.cls

                        call check_invariant
                        
                        ::options digits 2
                        ::options numeric noinherit
                        ::options noGlobalOverride  -- <-- <--
                        
                        ::routine check_invariant
                           if digits() == 2 then
                               say "No problem"
                           else
                               say "Who broke my invariant?"
                        

                        This will inhibit breaking the invariant in myPackageDigits2.cls by a global options override.

                        The code is in the patch "options_noglobal_override.diff" that got uploaded in the beginning of this thread.

                         
                        • jfaucher

                          jfaucher - 2025-12-21

                          Ah, ok. You use "push" for global overriding. My understanding of "push" was that the caller would push his numeric settings on to a required/called program.

                          yes, sorry for the confusion.

                          The latter, demonstrated with your set of programs, adding "::options noGlobalOverride" to myPackageDigits2.cls:
                          ...
                          This will inhibit breaking the invariant in myPackageDigits2.cls by a global options override.

                          Yes.

                          In addition to Dom's debugger, I think this declaration should be added in
                          * dateParser.cls, because a global numeric setting may break it (search for "numeric").
                          * bsf.cls, because it wouldn't work if a global noprolog is used.

                          Side note 1:
                          Doc to update in 5.1.5.29 Package options
                          In the syntax diagram, replace "All" by "SetPackageSettings".

                          I think that "SetPackageSettings" should be replaced by "OverrideOptions", to be aligned with the globalOptions method.

                          And I would not limit the test of option name to "S" or "O" because this setting is too impacting to be hidden behind a single letter. For code review, "Set" or "Override" would be a better abbreviation.

                          Side note 2

                          The attached file helped me to understand what you implemented. That's a lot of work, with a clever way to convert the option string into a PackageSetting instance.

                          Side note 3
                          Given the confusion surrounding the concepts of “push” and “pull,” I will attempt to clarify what I have tried to propose in my previous messages.

                          The global overriding is currently imposed (pushed) to the package owner, who has to protect his package with ::options noGlobalOverride.

                          The other approach I tried to propose was:
                          The global overriding is not imposed to the package owner.
                          The package owner decides if he accepts his options to be overriden (like a pull).
                          I caused confusion in my previous messages by using the term “inherit.”
                          A better declaration would have been ::options GlobalOverride

                          For this approach to work, PackageClass::setPackageSettings should raise an error if "GlobalOverride" is passed in the option string.

                           
                          • jfaucher

                            jfaucher - 2025-12-21

                            I find this answer to the second question better than the one I tried to explain in my own words:
                            https://chatgpt.com/share/69480f24-59f8-8007-9247-1cd8282cfec2

                            And that concludes my contribution.

                             
    • Rony G. Flatscher

      Hmm, how about defining ::OPTIONS suboption that start with "PROTECT" then, e.g.:
      * NOGLOBALOVERRIDE (no override whatsoever)
      * PROTECT DIGITS (do not change the DIGITS setting by the global override value)
      * PROTECT FORM (do not change the FORM setting by the global override value)
      * PROTECT FUZZ (do not change the FUZZ setting by the global override value)
      * PROTECT NUMERIC (do not change the NUMERIC setting by the global override value)
      * PROTECT ALL (do not change any ERROR/FAILURE/LOSTDIGITS/NOSTRING/NOTREADY/NOVALUE setting by the global override value)
      * PROTECT ERROR (do not change the ERROR setting by the global override value)
      * PROTECT FAILURE (do not change the FAILURE setting by the global override value)
      * PROTECT LOSTDIGITS (do not change the LOSTDIGITS setting by the global override value)
      * PROTECT NOSTRING (do not change the NOSTRING setting by the global override value)
      * PROTECT NOTREADY (do not change the NOTREADY setting by the global override value)
      * PROTECT NOVALUE (do not change the NOVALUE setting by the global override value)
      * PROTECT PROLOG (do not change the PROLOG setting by the global override value)
      * PROTECT NOPROLOG (do not change the NOPROLOG setting by the global override value)
      * PROTECT TRACE (do not change the TRACE setting by the global override value)

       
  • Dom Wise

    Dom Wise - 2025-12-22

    Is there a use case from 858/ 859 where it's necessary to override values already set by an ::OPTIONS directive in a package with "global" options or is it always sufficient to just allow defaults to be specified to be used only when a specific option is not already set by the package ?

    In this scenario GlobalOptions (or perhaps DefaultOptions) "TRACE...." will only take effect for a package if there is not already an ::OPTION TRACE directive in that package

    I ask because I've tried the patch (thanks again Rony) and it does what is expected for the debugger programs but there are some items that might benefit from further discussion arising from "default is to allow override (unless blocked by a new keyword)" when using the global class method or command line option.

    1. In order to block overrides that could come from running under 5.2 it is necessary to specify the new keyword, but this means the same source files cannot be loaded in older ooRexx versions that may be supported by the program since the new keyword would not be recognised. I might be wrong but I don't think there is a way to conditionally execute ::OPTIONS directives based on ooRexx version to work around this.

    2. Dependent modules loaded (e.g. ooDialog.cls, bsf.cls etc) will also pick up any global options active at the load time of the package which loads them and this could also cause problems for the program which calls them. This is certainly true for the debugger if any tracing is activated in, for example ooDialog.cls

    I'm wondering whether instead of having GlobalOptions there could just be "DefaultOptions", perhaps set/retrieved with DefaultOptions= and DefaultOptions methods. A package would not need to state whether it allows or blocks "overrides" with new keywords making backwards compatibility automatic. Instead, the presence of an ::OPTIONS directive for a particular option would prevent that option from being overridden by the default.

    The current -o option could still be used to "force" the initial package (presumably always under the control of the developer specifying the option) to use specific values but -og (or perhaps -od) would set default options that would only only picked up by packages that have not set their own values. There would be no need for an OverrideCount in this scenario

    The Rexx library packages shipped with ooRexx could perhaps have ::OPTIONS TRACE O specified so that by default they wont TRACE when DefaultOptions includes a TRACE option. Any other expected options can also be fixed in this way. If tracing does need to be switched on or any other option overridden the package level "options" method can be called to do this by the controlling program, and even this can be prohibited by the package if needed though the use of a Security Manager object. The only case where this could not be prohibited is for a top-level package where -o is specified but as indicated since this is the "main" program a developer should know what they are doing with this and not need to worry about additional Rexx packages it might be using.

    Of course, if there are specific use cases motivated the original enhancement request which cannot be met by the above then it can't be used, but it would be helpful to know what these might be so a

    Likewise my logic might just be plain wrong or missing other important details so please feel free to pile in!

    One final (positive!) point to note is that although the ooRexx debugger can't actually be run if -og is specified with a trace option, when run normally and after it has loaded its dependent "system" packages (e.g. oodialog.cls) it is nevertheless able to use the new GlobalOptions class method to activate automatic debugging for programs called by the main program without the need for source code modification of these "child" programs, which is a significant improvement over 5.1.

    Best Regards,
    Dom

     
    • jfaucher

      jfaucher - 2025-12-22
      Post awaiting moderation.
  • Rony G. Flatscher

    Thank you for your thoughts, efforts and considerations!

     
    • Rony G. Flatscher

      Sorry for being so brief, currently much family business and almost no free resources to turn to the computer... :(

      But one thing: this area is motivated for enabling debugging/tracing/profiling and testing. Or with other words: the command line options are not meant to be used for deployed programs.

      If someone debugs/traces/tests using the -og switch the person ought to know about the option settings she uses and possible negative effects. Or with still other words "-og" is a sort of a sledge hammer debugging/tracing/testing aid. :)

      Ad use cases beyond tracing: making it easy to test effects "what happens, if" (changing any option).

      Maybe an example for a use case which is not so terrifying ;) : if debugging a package it may make sense to disable the prolog, e.g. for tracint to help to see exactly what gets executed in the setup phase of a package (e.g. which class init/activate run and how).

      Again, sorry, it will take a few days before I will be able to be back. Will be happy if as many people discuss this area, and even more happy if a consensus can be built.

       
      • Rony G. Flatscher

        Going through all the postings, Dom‘s thorough and polite remarks suggest to not create a new options subdirective as this would inhibit using such ooRexx programs on earlier/other ooRexx versions. The global override should better be called default options, and would only be applied to a package if the respective options subdirective is not explicitly set in the package. This at the same time would simplify the need for explanations, making it very easy to communicate and to understand, very Rexxish! :)

        This would boil down to:
        - no new options subdirective (hence no new NOGLOBALOVERRIDE)
        - rename globalOptions (-og) to defaultOptions (-od)
        - memorize per package, which options subdirectives got explicitly defined
        - when applying the defaultOptions explictly defined options subdirectives do not get changed in a package

        Did I miss something? Any comments?

         
        • Rony G. Flatscher

          Implemented the above, added an argument "X" to Package' options method which returns the explicitly set options of a package; explicitly set options will not be changed by "-od".
          Committed with [r13052].

           

          Related

          Commit: [r13052]

          • Rony G. Flatscher

            Please note, the following change will also take place and are already reflected in the documentation update with [r13055].

            Package's defaultOptions method will now accept the option "D" for "defineDefaultOptions" instead of "O" for "overrideSettings".

            (The code changes will be committed later, such that the new documentation builds can be included then.)

             

            Related

            Commit: [r13055]

            • Rony G. Flatscher

              Tests [r13056], code [r13057].

               

              Related

              Commit: [r13056]
              Commit: [r13057]

1 2 > >> (Page 1 of 2)

Anonymous
Anonymous

Add attachments
Cancel