Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2021 - online Python 3 training - see ((here)).

Our plans were to retire in summer 2020 and see the world, but Coronavirus has lead us into a lot of lockdown programming in Python 3 and PHP 7.
We can now offer tailored online training - small groups, real tutors - works really well for groups of 4 to 14 delegates. Anywhere in the world; course language English.

Please ask about private 'maintenance' training for Python 2, Tcl, Perl, PHP, Lua, etc.
Passing lists into procedures

Posted by Graham_Tasker (Graham_Tasker), 30 March 2005
Here follows a frament of code that is giving me learl problems :

#=======================================================================

proc satOps::nextElement { oldListVar } {

   upvar $oldListVar oldList

   $::log debug ">> called satOps::nextElement with oldListVar = $oldListVar  <<"
   
   set oldListLength [ llength $oldList ]

   $::log debug ">> listVar = $oldList, length = $oldListLength <<"
   
   if { $oldListLength > 0 } {
   
       set result [ lindex $oldList 0 ]
       
       if { $oldListLength > 1 } {
       
           set oldList [ lrange $oldList 1 end ]  
 
       } else {
       
           set oldList {}
   
       }
       
   } else {
   
       set result {}
       
   }        
   
   $::log debug ">> listVar now = $oldList, result = $result  <<"
   
   return $result

}

#=======================================================================

... ... ...

   
   $::log debug ">> args = $args <<"
   
   while { [ llength $args ] > 0 } {

       set presentEntry [ string tolower [ satOps::nextElement args ] ]
       
       $::log debug ">> presentEntry = $presentEntry <<"
   
       switch -regexp -- $presentEntry {

the following is happening

>> args = no { 0.0 0.0 0.0 0.0 } 10 10 0.01 0.002 0.002 5 1 1 1 { 0.0 0.0 0.0 0.0 } 0 0 0 <<
>> called satOps::nextElement with oldListVar = args  <<
>> listVar = {no { 0.0 0.0 0.0 0.0 } 10 10 0.01 0.002 0.002 5 1 1 1 { 0.0 0.0 0.0 0.0 } 0 0 0}, length = 1 <<
>> listVar now = , result = no { 0.0 0.0 0.0 0.0 } 10 10 0.01 0.002 0.002 5 1 1 1 { 0.0 0.0 0.0 0.0 } 0 0 0  <<
>> presentEntry = no { 0.0 0.0 0.0 0.0 } 10 10 0.01 0.002 0.002 5 1 1 1 { 0.0 0.0 0.0 0.0 } 0 0 0 <<

As you can see the procedure nextElement thinks the list is 1 element long not 15, returns the complet list and sets args to an empty list. what I want is the first element in the list and args holding the remaining 14 elements for future processing.

Note that the procedure working happly with other llists generated else were in the program.

what is happening?


Posted by admin (Graham Ellis), 31 March 2005
Graham - I've sat scratching my head and trying to engage brain.  I suspect the problem is because you're passing args which is a "special" - a sort of superglobal.   Have you tried copying args to another variable and passing that ?

Posted by Graham_Tasker (Graham_Tasker), 31 March 2005
I am affraid so, and I still get the same problem.

Posted by admin (Graham Ellis), 31 March 2005
Looks like there's an extra set of curly braces on the data passed in ... all the data is passed in correctly, but the extra braces make the whole thing a list with one element (which is itself a list). Do I make sense?   I'll come back to have a look at this if I get a chance later today ... do post a follow up if I've given you a vital clue and come up with a solution though  

Posted by Graham_Tasker (Graham_Tasker), 31 March 2005
I am getting some were at last, your responce about 'args' started me thinking, here is a bit more of the code :

proc satOps::TC { tcname args } {
....

           set params [   makeSendTcPerformScmRasterPointingV1 $args ]    

.... }

proc satOps::makeSendTcPerformScmRasterPointingV1 { args } {
..........  }

and the first call

   satOps::TC PERFORM_SCM_RASTER_POINTING_V1 \
       no                                    \
       { 0.0 0.0 0.0 0.0 }                   \
       10                                    \
       10                                    \
       0.01                                  \
       0.002                                 \
       0.002                                 \
       5                                     \
       1                                     \
       1                                     \
       1                                     \
       { 0.0 0.0 0.0 0.0 }                   \
       0                                     \
       0                                     \
       0

right then the following is happening :

the first call (satOps::TC) is converting all the parameters except the first into a list, the action of the args parameter. This is then passed to the second call were again the parameter is 'args' which of couse converts its arguments into a list so we are converting a list into a list  which means that the multipul element list wich is the result of the call to satOps::TC becomes a single element list following the call to satOps::makeSendTcPerformScmRasterPointingV1. Long winded yes, but the upshot of this is :

Be very careful when nesting procedures with the 'args' parameter, you may not end up with what you think

esoteric I think  

Graham Tasker  




Posted by admin (Graham Ellis), 1 April 2005
Yes, Tcl has odd esoteric things like this from time to time. One of my other favourites is programs which suddenly go wrong when the input data starts withs with a "-" sign as it gets taken as an option ... often after years of working correctly!

Anyway - I'm glad you've got that vital clue now and are there (or nearly there) with a solution / alternative code!

- Graham

Posted by iusharief (iusharief), 11 May 2005
Did anyone try out for a solution for this problem... I have been facing this problem for quite some time ... Happy to see that there is atleast one forum where I can discuss about this problem with those who are facing it.

Posted by Graham_Tasker (Graham_Tasker), 11 May 2005
As given in my replay above the problem is caused by using the general parameter 'arg' which causes all remaining paramaters after those which can be assigned to parameter names to be converted into a list. If this list is then passed toa second procedure which also uses the 'arg' parameter the multipul element list is inserted into  a new list as a single element.

Thus given the following code fragment :

proc exam1 { arg } { ... }

proc exam2 { p1 arg } {
...
exam1 arg
...
}

exam2 a b c d e

the proc exam2 parameters will hold

a1 = a

arg = { b c d e }

the proc exam1 parameter will hold

arg { { b c d e } }

Note howthe list in exam2 has become a single element within the lists in exam1.

The upshot of this is be careful when using 'arg' try to handle the contents in the first procedure and not the second.



Posted by iusharief (iusharief), 11 May 2005
Yes ... I had got what u had mentioned earlier...
But I wanted a solution for this ... as in my case I have a huge number of nested procedure calls and it is working fine in a large number of nested procedures but it breaks in only one particular procedure which is the 1st nested procedure (in the example it is "exam1") due to the problem that it is passinge the args as a single list...

However I am using the following workaround in my 1st nested procedure and then it seems to work fine (though the method is an haphazard way)

proc exam1 { arg } {
### workaround ###
   if {[llength $arg] == 1} {
     set arg [lindex $arg 0]
   }
###############
......................
}

proc exam2 { p1 arg } {
...
exam1 arg
...
}

This workaround works fine as long as the we do not send only one arguement of list type.



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2021: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho