This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Weird behavior of FOREACH command

Help for those learning Tcl or writing their own scripts.
Post Reply
User avatar
z_one
Master
Posts: 269
Joined: Mon Jan 14, 2002 8:00 pm
Location: Canada

Weird behavior of FOREACH command

Post by z_one »

Code: Select all

# list of channels 
set thechanlist "#chanA #chanB #chanC" 

proc whereisthebot {} { 
  global thechanlist
  foreach chan $::thechanlist { 
    if {[botonchan $chan]} { 
      putlog "$botnick is on $chan" 
    } 
  } 
} 
Then in the bot .conf file I have added ChanA, ChanB and ChanC in this exact order. The script works fine.

Now, whenever I set the variable thechanlist to "#chanC #chanA #chanB" for example ... then the foreach loop just goes over ChanC and doesn't go over the two other chans.

I don't get it. What does the variable thechanlist have to do with the bot's .conf file ?
User avatar
CrazyCat
Revered One
Posts: 1304
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

You set a string, not a list or array.
You can use:

Code: Select all

# list of channels
set thechanlist {"#chanA" "#chanB" "#chanC"}
proc whereisthebot {} {
  foreach chan $::thechanlist {
    if {[botonchan $chan]} {
      putlog "$botnick is on $chan"
    }
  }
}
Or if you want to keep your initial setting:

Code: Select all

# list of channels
set thechanlist "#chanA #chanB #chanC"
proc whereisthebot {} {
  foreach chan [split $::thechanlist " "] {
    if {[botonchan $chan]} {
      putlog "$botnick is on $chan"
    }
  }
}
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

@CrazyCat:

Code: Select all

{"#chanA" "#chanB" "#chanC"}
This is just as much a string as the code used by z_one..
To make proper list, use the list-command (or split).
Ie:

Code: Select all

set thechanlist [list #chanA "#chanB" {#chanC}]
@z_one:
If you use the global-command to link a localspace variable to the globalspace one, you don't need to use full namespace paths for that variable. In the same way, if you use full namespace path, there is no reason to use "global". Nothing wrong with doing both I guess, except that you might forget that the localspace variable is linked to the globalspace in larger scripts.

I do however notice that you try to access the globalspace variable botnick as a localspace variable without using "global". This should cause an error, and prematurely abort the proc with an error condition.
NML_375
User avatar
z_one
Master
Posts: 269
Joined: Mon Jan 14, 2002 8:00 pm
Location: Canada

Post by z_one »

Yeah, sorry about that botnick thing ... I forgot to copy it here as I was typing the code manually.

So basically, nml375, if I use the list-command I can use any of the following ?

Code: Select all

set thechanlist [list #chanA #chanB #chanC]
OR

Code: Select all

set thechanlist [list "#chanA" "#chanB" "#chanC"]
OR

Code: Select all

set thechanlist [list {#chanA} {#chanB} {#chanC}]
I think Crazycat's second example should work too because the split-command would turn the string "#chanA #chanB #chanC" into a list right ?

Thank you both for the replies.
User avatar
CrazyCat
Revered One
Posts: 1304
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

@nml375: I know the way I use is not really good, but it works.

@z_one: the second example I gave is working because it use the logical way to transform a string into a list.
User avatar
Dedan
Master
Posts: 260
Joined: Wed Jul 09, 2003 10:50 pm
Location: Memphis

Post by Dedan »

and stop using list commands on strings.
split the sting into a var and then
use the foreach ....

global botnick
if the botnick var was not called then it will produce
an error and stop the loop
I once was an intelligent young man, now i am old and i can not remember who i was.
Post Reply