Persistent variable between messages

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Persistent variable between messages

  • Creator
    Topic
  • #55732
    Jerry Tilsley
    Participant

      All,

      I’m trying to make a keyed list variable that is shared between messages in the same proc/thread.  What is the best approach to this?

      Thanks,

      Jerry

    Viewing 5 reply threads
    • Author
      Replies
      • #86329
        Mark Thompson
        Participant

          Hello Jerry,

          It depends.  Does the keyed list need to survive a restart of your Cloverleaf process or thread?

          If not, you can use a global variable to store the keyed list.

          Code:

          global myKL

          Or even better, put it in a namespace.

          Code:

          # Initialize the variable during startup
          namespace eval ::myNamespace {variable myKL}

          # Set a value
          keylset ::myNamespace::myKL SOMEKEY $someValue

          # Retrieve a value
          set variableName [keylget ::myNamespace::myKL SOMEKEY]

          or more robust

          Code:

          if { ![keylget ::myNamespace::myKL SOMEKEY variableName] } {
           # Error processing here – key not found
           # puts “my stuff couldn’t retrieve SOMEKEY in ::myNamespace::myKL”
          }

          or even more robust

          Code:

          if { [catch {keylget ::myNamespace::myKL SOMEKEY variableName} errTxt] } {
           # Error processing here – covers all kinds of errors
           puts “my stuff failed because $errText”
          }

          If you need to persist through a restart use a file or database.

          - Mark Thompson
          HealthPartners

        • #86330
          Charlie Bursell
          Participant

            To make sure of no Tcl error when attempting to access I always do something like this:

            Namespace

            namespace eval ::myNamespace {if {![info exist myKL]} {set myKL “”}}

            Global  (Note global is also a name space

            if {![info exist ::myKL]} {set ::myKL “”}

            The above should be in any proc that uses the variable prior to accessing.  Afterwards the proc can access or modify the variable as required whether keyed list or other variable

            The second paradigm is the one I use in a route proc if I need a global since there is no startup (by default) in which to initialize.

          • #86331
            Jeff Dinsmore
            Participant

              A slight correction (perhaps a typo):

              it should be:

               info exists myKL

              rather than:

               info exist myKL

              Tcl is kind enough to interpret “exist” correctly, but it’s better to use the full operator.

              I was testing a little and was amused that “info e myKL” works in my interpreter as well, but I wouldn’t bank on that…

              Jeff Dinsmore
              Chesapeake Regional Healthcare

            • #86332
              Jerry Tilsley
              Participant

                I could not get the globals to work, so I went ahead and just went with a sqlite database lookup.  Thank you all for your suggestions!

                Jerry

              • #86333
                Charlie Bursell
                Participant

                  Tcl will interpret the command as long as there is enough to not be ambiguous.   Personally I prefer and use exist more often than exists.

                  To each his own  ðŸ˜€

                • #86334
                  Jeff Dinsmore
                  Participant

                    I have to respectfully disagree, Charlie.

                    Shorthand is fine for interactive shell use, but will eventually bite you when used in reused/production code.

                    For example, this works in the Tcl 8.5.10 running on my CL server:

                    Code:


                    set mylist [lis aa bb cc]

                    if { [info e myKl] } {
                     set f [op /tmp/j.txt w]
                     put $f “length of mylist= [lle $mylist]”
                     close $f
                    }

                    But, it fails with an error in version 8.6.7 on my desktop:

                    Code:

                    unknown or ambiguous subcommand “e”: must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars

                    Likewise, as soon as I define a new command that starts with “op”, my shorthand open command “op” is no longer unique.

                    So, I create this proc:

                    Code:

                    proc operationCloverleaf { } {

                     puts “this is a new command”
                     
                    }

                    Then re-run my original code and get this error:

                    Code:


                    Error: ambiguous command name “op”: open operationCloverleaf

                    The same holds true for the lis, lle and put abbreviations I used.  Even though they may work today, that doesn’t mean they’ll continue to do so over time.

                    So, for the sake of maintainability, any production code should have full command syntax.  That way, when something changes in the future, it doesn’t unexpectedly break your old code.

                    Jeff Dinsmore
                    Chesapeake Regional Healthcare

                Viewing 5 reply threads
                • The forum ‘Cloverleaf’ is closed to new topics and replies.