MSGID – message header – pass by reference?

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf MSGID – message header – pass by reference?

  • Creator
    Topic
  • #50853
    Steve Pringle
    Participant

      I’m somewhat new to tcl, so please bear with me…

      I’ve got a TPS Proc that references a message handle.  I find that when I pass the message handle as an argument to a “local” proc that any modifications made to the message handle are global.  This surprises me as I thought you couldn’t pass by reference unless you used “upvar”.

      Specifically, if I pass $newmh as an arg to my local proc, where the local proc does a msgappend, the message header retains the changes in the “main” proc.  I had expected the changes to the message header in the “local” proc NOT to be retained in the “main” proc due to scoping…

      Is there some unseen environment setting in TPS procs that allow for this, or am I just missing the obvious?

      thanks,

      Steve

      Here’s my “local” proc, in the same file as my TPS proc, followed by the TPS proc that calls the “local” proc – processAOE:

      Code:

      proc processAOE { mh obx debug } {

         # get the test code type
         set comp [getHL7Comp $obx 3 1]

         if {$debug} {
             # name of this procedure
             set module [lindex [info level [info level]] 0]

             echo “in $module: OBR:3.1 = $comp”
         }

         # build a new obx containing the question & answer
         switch — $comp {
            do some stuff here…

                 # just add the segment and we’re done
                 msgappend $mh $obx
                 msgappend $mh “r”
             }
         }
      }

      proc breakout4medicaAOE { args } {
         global env HciSiteDir HciConnName

         keylget args MODE mode    ;# fetch mode

         set dispList {}           ;# nothing to return

         switch -exact — $mode {
             start {
                 # Perform special init functions
                 # N.B.: there may or may not be a MSGID key in args
             }

             run {
                 # defaults
                 set debug 0

                  # get debug flag
                 keylget args ARGS.DEBUG debug

                 # ‘run’ mode always has a MSGID; fetch and process it
                 keylget args MSGID mh

                 # get the msg
                 set msg [msgget $mh]

                 …  do stuff here

                 set newmh [msgcopy $mh]

                 # set the message data to null, since we’re generating a new msg
                 msgset $newmh “”

                 … do more stuff here

                     # process the OBX segment if it’s prenatal
                     if { $prenatal && [cequal $seg “OBX”] } {

                         # CALL processAOE HERE – no return value to save…
                         processAOE $newmh $segment $debug

                     } elseif { $seg != “” } {
                         msgappend $newmh $segment
                         msgappend $newmh “r”
                     }
              }

                 if {$debug} { echo “new msg is:n[msgget $newmh]” }

                 # send the new msg on
                 lappend dispList “CONTINUE $newmh”

                 # and kill the old msg
                 lappend dispList “KILL $mh”
             }

    Viewing 3 reply threads
    • Author
      Replies
      • #67782
        Sergey Sevastyanov
        Participant

          Steve,

          Your local proc changes message data – (msgappend changes the message data), not the handle.

          $newmh is just a handle (or pointer, reference, whatever) that points to actual message data. So when you change message data it doesn’t matter if you change it in local proc or in calling proc.

          If you were changing the handle itself (for example, set newmh 0) in your local proc, you’d find that it didn’t affect the handle in your calling proc, where you still would be able to access message using that handle.

        • #67783
          Steve Pringle
          Participant

            Sergey,

            I agree, the $newmh is behaving like a pointer.  What’s confusing is that TCL doesn’t have pointers, or so I thought.

            found the following at <a href="http://wiki.tcl.tk/1089&#8243; class=”bbcode_url”>http://wiki.tcl.tk/1089

            Quote:

            In general, Tcl doesn’t expose pointers to the user. Instead, the model that Tcl uses is that of a handle. A handle is a synthetic string value, generated in some manner by Tcl, and which is used to represent the actual pointer.

            One example of such a pointer in Tcl is the value returned by the Tcl open command. The string returned begins with the value “file” followed by a number. Tcl maps this string internally to an open file pointer when it is time for the interpreter to do some file I/O against that particular file.

            So – is the cloverleaf tcl environment doing something behind the scenes (ala open) that makes a message handle a pointer?

            What type of data structure is a message handle?  A list?  An array?  I couldn’t find anything in the Cloverleaf documentation on this subject.

            I’m guessing a message handle is a handle/pointer, ala open.

            Here’s a case where a list is passed as an arg, but it’s passed by value, not reference:

            Code:

            #! /quovadx/qdx5.3/integrator/bin/hcitcl

            proc editList { aList } {
               set fieldID 3
               set data “UNKNOWN”

               echo “before replace aList: $aList”
               set aList [lreplace $aList $fieldID $fieldID $data]
               echo ” after replace aList: $aList”
            }

            set segment “OBX|1||A1^Due Date, Determined By|”

            set fieldList [split $segment |]

            echo “fieldList: $fieldList”
            echo “calling editList…”

            editList $fieldList
            echo “fieldList: $fieldList”

            output:

            fieldList: OBX 1 {} {A1^Due Date, Determined By} {}
            calling editList…
            before replace aList: OBX 1 {} {A1^Due Date, Determined By} {}
            after replace aList: OBX 1 {} UNKNOWN {}
            fieldList: OBX 1 {} {A1^Due Date, Determined By} {}

            thanks,

            Steve

          • #67784
            Charlie Bursell
            Participant

              OK guys this is not brain surgery  ðŸ˜€

              A message handle is a system level pointer to a structure in memory.  It is analogous to a file handle like; set fh open foo].

              When you pass to a child program you are passing a value like message0 which is still a valid pointer to a message structure.  Remember you are still within the same Tcl interpreter.  If were to pass the file handle as above, it would work similarly.

              It is not a matter of how Cloverleaf works it is a matter of how Tcl, and most other languages, works.

            • #67785
              Steve Pringle
              Participant

                Got it!

                I’ve never created a system level pointer to a structure in memory in tcl.

                In my little world of Cloverleaf tcp procs I don’t see system level pointers (generated from a Cloverleaf tcl lib call) very often!

                thanks,

                Steve

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