MSGID – message header – pass by reference?

Homepage 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.

Forum Statistics

Registered Users
5,042
Forums
28
Topics
9,200
Replies
34,021
Topic Tags
267