Accessing namespace procs

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Accessing namespace procs

  • Creator
    Topic
  • #51699
    Deborah Slater
    Participant

      We have 3 little procs coded within a .tcl which lay within a namespace which allow us to write data to a file when processing an inbound message and then retrieve that data to associate it with the outbound message.

      We want to reuse these procs during translation on another site, but we are getting error:

      Xlate ‘NewOrderIn.xlt’ failed: Tcl callout error

      erroCode: NONE

      errorInfo:

      invalid command name “connid::write”

         while executing

      “connid::write $connid

           (procedure “xltAAHGenConnID” line 20)

           invoked from within

        “xltAAHGenConnID”

        I can see the procs in the tclIndex (and as expected without the namespace qualifier).

        I have tried adding:

         namespace export write in the original file

        and

         package require connid in the new proc

        but then I get the cannot find package error.

        I’ve been reading Chpt 14 in the Welch book, but it looks like I should be able to access the proc just with the connid:: namespace identifier, so I don’t know what I am doing wrong. Any suggestions greatly appreciated.

    Viewing 6 reply threads
    • Author
      Replies
      • #71347
        Charlie Bursell
        Participant

          Have you declared the file that has these procs to be a package?

             package provide [version]

          After that you must make a package index.  If you have 5.7 we now ship a script with it similar to mktclindex named mkpkgindex.  mkpkgindex, by default expects files with extention of .pkg.  Of course you can override it by providing the extension, i.e., mkpkgindex “*.tcl”

          YOu must then hav eyour package in the serach path.  Tcl with search the path in the auto_path global and one level deeper.  For packages to be used in a site I normally put mine in HCISITEDIR/tclprocs/lib.

          Another option would be to source the file before you attempt to access the namespac procs in it, i.e.  source

        • #71348
          Deborah Slater
          Participant

            Thansk for the reply Charlie.

            I will have to investigate the whole package topic, as I don’t think this is something used here before. Which confuses me as I have examples of the procs I want to access being run in 2 different sites with the same qualified call structure and without any package require statements. Indeed there are no export statements in the tcl file containing the declaration of the namespace procs.

            The only differences I can find between the working sites and my site are:

               the working sites are being called from the inbound thread configuration tab in TPS Inbound Data, whereas on my site, I am trying to call the namespace proc from a copy statement in the translation.

              The other difference between the working sites and my one is that there are half a dozen procs in the .tcl file – three inside the namespace and three outside. On both the working sites there is a call to one of the procs outside the namespace first, whereas in my site all I am calling is a proc inside the namespace. Would this have any affect?

            In the meantime, I will look at the namespace export command and creating a package.

          • #71349
            Scott Folley
            Participant

              I am going to take a guess that they work in the Inbound-TPS because the required packages are sourced in the startup mode.  Translations procs do not run in startup mode unless you specifically tell them to in the process configuration.  This is just a guess but post the proc that you are trying use and we can see.

            • #71350
              Deborah Slater
              Participant

                Scott,

                Thank you for agreeing to look further at my namespace proc access problem. Attached is the file containing the procs I am trying to access on the Xlate copy statement. I particularly want to use the connid::write, connid::read and connid::delete procs.

                Deborah

              • #71351
                Scott Folley
                Participant

                  Are you accessing these procs or are you trying to access that namespace with a separate proc or code snippet within the Xlate?

                  If you are trying to use it as a separate code snippet that would not work because this package is defined within this set of code only and is not exported to make it available outside of this source file.

                  If you are trying to use the procs in this file that then access the package, then it should work.

                  This is true because of the way that TCL looks for proc names, the first place that it looks is within the current source code file, then it looks in the current site’s tclprocs directory, then the master site’s tclprocs directory, then the root’s tclprocs directory, etc etc.

                  What you need to do is pull the connid portion of this TCL file out into its own package, wrap it in the necessary exports, and then you will have to do a “package require” on it within the code snippet in the translate prior to using the connid namespace commands.

                  I will see if I can give you a headstart on that and post it back to you.

                • #71352
                  Scott Folley
                  Participant

                    Okay, here is what it will need to look like:

                    Put the connid.pkg file in your root tclprocs directory or your master site tclprocs directory and put the pkgIndex.tcl file in that same directory.  When you want to use the connid package just put in “package require connid” prior to using them and you should have access to them.

                    As always, there is a caveat.  Before you put the pkgIndex.tcl file in place look to see if there is already one there.  If there is then you will want to add the package ifneeded command to that file instead of replacing the file.

                    Have fun!

                    connid.pkg

                    Code:



                    package provide connid [lindex {Revision: 1.0 } 1]
                    ######################################################################
                    # Name:         connid
                    # Purpose:      Write, read, and delete connids from connid.dat file
                    # UPoC type:    none (namepsace)
                    #               Note a namespace is used to make these procs “private” and
                    #               prevent them from appearing in Cloverleaf dropdown lists
                    #               in the IDE.
                    #
                    # Procedures:
                    #
                    #       connid::write
                    #               args: connid = connid to store
                    #                     clist  = list of data associated with connid
                    #                       (ip, port, type, format, valid)
                    #               returns: nothing
                    #
                    #       connid::read
                    #               args: connid = connid to read
                    #               returns: list of information associated with connid
                    #
                    #       connid::delete
                    #               args: connid = connid to delete
                    #               returns: nothing
                    #
                    namespace eval connid {
                       variable fname
                       set fname connid.dat

                       proc write { connid clist } {
                           variable fname

                           # If the file exists we need to update it
                           # If the file does not exist simply create it
                           set kl “”
                           if { [file exists $fname] } {
                                   set fd [open $fname r]
                                   flock -read $fd
                                   set kl [gets $fd]
                                   close $fd
                           }

                           set fd [open $fname w]
                           flock -write $fd

                           keylset kl $connid $clist

                           puts $fd $kl
                           close $fd
                       }

                       proc delete { connid } {
                           variable fname
                           # Delete the specified connid
                           if [file exists $fname] {
                                   set fd [open $fname r]
                                   set kl [gets $fd]
                                   close $fd

                                   set fd [open $fname w]
                                   flock -write $fd
                                   catch { keyldel kl $connid }
                                   puts $fd $kl
                                   close $fd
                           }
                       }

                       proc read { connid } {
                           variable fname

                           set fd [open $fname r]
                           flock -read $fd
                           set kl [gets $fd]
                           close $fd

                           if [catch { keylget kl $connid } cinfo] {
                                   logit 0 “No data found for connid $connid!”
                                   set cinfo “”
                           }

                           return $cinfo
                       }
                    }; # End of connid namespace

                    pkgIndex.tcl

                    Code:


                    # Tcl package index file, version 1.1
                    # This file is generated by the “pkg_mkIndex” command
                    # and sourced either when an application starts up or
                    # by a “package unknown” script.  It invokes the
                    # “package ifneeded” command to set up package-related
                    # information so that packages will be loaded automatically
                    # in response to “package require” commands.  When this
                    # script is sourced, the variable $dir must contain the
                    # full path name of this file’s directory.

                    package ifneeded connid 1.0 [ list source [file join $dir connid.pkg] ]

                  • #71353
                    Deborah Slater
                    Participant

                      Hello Scott

                      On the initial site that these namespace procs were written for:

                          On the inbound TPS Inbound Data window, the proce tpsValidateBroadbandOrder is called and from within this proc there is a call to connid::write

                      On the second site that uses the namespace proc, the same formula is used – it calls the tpsValidateBroadbandOrder on the inbound TPS Inbound Data window

                      I just wanted to call the connid::write proc on a new site to save some data during the Xlate process, so I added the connid::write command to the tcl code : xltAAHGenConnID (attached) which is accessed on an xlate copy statement in the pre TCL Input/Ouput window. (You will see that I have noted out the call to connid::write and added in all the code as I needed to make the site avaiable for testing last week, but it would obviously be better to have the write proc just once and use it across our different sites.)

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