| View previous topic :: View next topic |
| Author |
Message |
johne Voice
Joined: 19 Jul 2005 Posts: 29
|
Posted: Mon Oct 06, 2008 7:48 pm Post subject: utimer with an if statement |
|
|
i have a join bind which calls a proc with the usual n u h c args, when the following line is performed, i get an error
| Code: |
utimer $::timer1 [list if {[onchan $n $c] && ![isop $n $c]} { putserv "PRIVMSG $c :[string map -nocase "%n $n" [random $::line1]]" }]
can't read "n": no such variable
|
any ideas why it wouldnt be able to find the $nick var?
Thanks |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon Oct 06, 2008 8:35 pm Post subject: |
|
|
It is because n is not available in globalspace when the timer triggers..
This requires an in-depth understanding of the command and variable substitutions done by the tcl interpreter. Roughly put however, any parameter enclosed with {} will not be processed for variable nor command substitutions, but instead passed on to the command as is.
In your case, both the condition and if_true parameters are enclosed with {}, and neither have any variable substitutions within the proc. When the timer triggers, the commandline is executed. The if-command then evaluates the first parameter (in the same fashion as calling eval) and tests the result; this will trigger both command and variable substitutions. However, neither n or c are now available, as the nameless space in the proc that created the timer has now been destroyed. Same applies for the if_true parameter.
Solving this, unfortunately, is not as easy as replacing {} with "", as it is very easy to accidentally pass the content of c and n to the interpreter, and unwanted substitutions are done - possibly leading to both your eggdrop and shell being compromised.
One way around this could be to save the values into some globalspace variable or array, and only pass an id to the timer-code rather than the variable contents. Since you're in control of the id, you could craft it in such manner that it is "safe". This would of course add some overhead to your script in order to maintain and clear this "storage"... _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
johne Voice
Joined: 19 Jul 2005 Posts: 29
|
Posted: Mon Oct 06, 2008 8:44 pm Post subject: Re: utimer with an if statement |
|
|
| ahh :/ thanks for your explanation. |
|
| Back to top |
|
 |
r0t3n Owner
Joined: 31 May 2005 Posts: 507 Location: UK
|
Posted: Tue Oct 07, 2008 7:53 am Post subject: |
|
|
Why not just create a seperate proc.. and call it with var arguments..
| Code: | proc dostuff {n c line} {
if {[onchan $n $c] && ![isop $n $c]} {
putserv "PRIVMSG $c :[string map -nocase { %n $n } [random $line]]"
}
} |
and call it with:
| Code: | | utimer $::timer1 [list dostuff $n $c $::line1] |
This saves creating an array, id system, updating and removal of such id's from the array, and generally more understanding and simple.. _________________ r0t3n @ #r0t3n @ Quakenet |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Tue Oct 07, 2008 1:52 pm Post subject: |
|
|
You're right, Tosser..
Curse of the tcl-wizard at work again:
Always overwork things overlooking the very simple solutions. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
|