| View previous topic :: View next topic |
| Author |
Message |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Wed Jul 14, 2010 12:16 pm Post subject: cannot unset an element in an array under certain conditions |
|
|
Hello,
I've taken some ideas, and bits and pieces of script that I've found around, and made myself a script to hold some info, when a user parts the channel.
Like this:
| Code: |
set array_name([string tolower $nick],$chan) "$nick $uhost $chan [unixtime]"
|
Seems to work fine.
When the user returns to the channel, script has bot say something like, "Welcome back nick, it has been xx minutes(seconds, whatever) since you were last here".
| Code: |
foreach item [array names array_name] {
(here, compare hostmask stored in array, to current $host ... if it matches, then announce, etc.)
|
This too, seems to work fine.
At this point, I want the script to unset the saved info. To get rid of it.
| Code: |
array unset array_name $item
|
This works fine too, until somebody has a nick with square brackets in it.
Usually, $item would be something like: somenick,#chan and it works.
However, if the user had a nick with brackets in it:
[s]omenick,#chan - then it doesn't work.
I've played around with [split $item] and [join [split $item]] in the script.
No luck.
Next, I tried doing it "by hand", in partyline with .tcl array unset. I can't get it to unset with:
.tcl unset array unset [s]omenick,#chan and it errors with unknown command of course.
Next I tried, .tcl array unset {[s]omenick,#chan} and it didn't error... but it didn't unset it either.
So far, the only way I've been able to do it from the partyline command line is: .tcl array unset {\[s\]omenick,#chan}
Using the backslash to escape the brackets does work.
I thought that if I could manipulate my varname and element such that the element was enclosed in curly braces, I'd be ok.
( http://www.peterre.info/characters.html )
Apparently, I'm overlooking something.
I hope I've made no confusing typos in this post... I've looked at the script so much and tried so many things now, that it is almost all a blur.
It is really bugging me now.
If someone could explain to me how to do it, and what my mistake is, I would like that very much.
Thanks |
|
| Back to top |
|
 |
speechles Revered One

Joined: 26 Aug 2006 Posts: 1398 Location: emerald triangle, california (coastal redwoods)
|
Posted: Wed Jul 14, 2010 2:33 pm Post subject: |
|
|
| Code: | | unset array_name($item) |
This will safely unset one element of your array.  _________________ speechles' eggdrop tcl archive |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Wed Jul 14, 2010 3:19 pm Post subject: |
|
|
| speechles wrote: | | Code: | | unset array_name($item) |
This will safely unset one element of your array.  |
Thanks for the reply.
With a quick test from the command line in partyline - yes, it seems to work.
But... only if I use the variable.
If I use the exact same info as is contained in the variable, ... just type it in... then the command fails, as it is trying to evaluate whatever it sees inside the square brackets.
What's the difference? this is baffling. The info is exactly the same.....
doesn't $item appear to TCL as the same info as when I type it in, using no variable?
Also, was I doing something wrong, with using array unset ? It looked like it was the right way to do it, to me. I just wonder how I got so far astray.
I'm headed out to edit my script, and do some testing for real now.
I'll comment on how it worked out, later.
Many thanks. |
|
| Back to top |
|
 |
speechles Revered One

Joined: 26 Aug 2006 Posts: 1398 Location: emerald triangle, california (coastal redwoods)
|
Posted: Wed Jul 14, 2010 5:12 pm Post subject: |
|
|
| Quote: | <speechles> .tcl set my_array(\x5bhello\x5d) "testing testing 1 2 3"
<bot> Tcl: testing testing 1 2 3
<speechles> .tcl set b $my_array(\x5bhello\x5d)
<bot> Tcl: testing testing 1 2 3
<speechles> .tcl set a [array names my_array]
<bot> Tcl: {[hello]}
<speechles> .tcl set my_array(\[hello\]) "\[ is the same as \x5b, but \x5b being evaluation safe ;)"
<bot> Tcl: [ is the same as [, but [ being evaluation safe ;)
<speechles> .tcl set a [array names my_array]
<bot> Tcl: {[hello]}
<speechles> .tcl set b $my_array(\x5bhello\x5d)
<bot> Tcl: [ is the same as [, but [ being evaluation safe  |
This is proof that the parenthesis of the array element are evaluated in the presence of brackets []. The trick is shown above, use the power of evaluation to defeat it. Use the x-encoding value (hex) of the bracket you wish and it effectively becomes an escaped bracket of the exact type you've used, right or left. This same method works for all characters.
| willyw wrote: | | doesn't $item appear to TCL as the same info as when I type it in, using no variable? |
The short answer is "NO". Tcl expects a variable to be post processed (known as already evaluated). Whereas your partyline/command-line approach is expected to be pre-processed. Your expected to issue commands, whereas issuing commands from within variables is somewhat rare (..and why [subt]/[eval] with tcl-filters exist). This is why you must use escapes (\), x-encoding(hex), u-encoding(unicode), etc .. to prevent these special characters from influencing Tcl. The long answer is a quiet "...yes", but to explain why would cause a hole in the fabric of time/space and cause a giant rift which might cause the Earth to vanish as if it never existed. So is easier to just say "NO"...
http://www.peterre.info/characters.html
This explains how this further affects substitution and evaluation order. So reading it is advised as well.  _________________ speechles' eggdrop tcl archive |
|
| Back to top |
|
 |
willyw Revered One
Joined: 15 Jan 2009 Posts: 1175
|
Posted: Sun Jul 18, 2010 7:09 pm Post subject: |
|
|
It appears that the solution you proposed above, works.
Thank you.
Wow... I didn't realize I'd touched on something so deep.
Thanks for trying to explain.... I'm not sure I got it all, but that's not your fault.
That's the one I mentioned earlier. It too has some things in it, that even though I've read over it, I don't fully grasp. It is bookmarked here though.
What was wrong with my trying to use array unset though?
It sure looked like a workable command, when I looked it up. Is this just a quirk... that it won't work in this case? |
|
| Back to top |
|
 |
thommey Halfop
Joined: 01 Apr 2008 Posts: 73
|
Posted: Mon Jul 19, 2010 9:05 am Post subject: |
|
|
| Quote: |
array unset arrayName ?pattern?
Unsets all of the elements in the array that match pattern (using the matching rules of string match).
-- snip --
| (emphasize mine). from http://www.tcl.tk/man/tcl8.5/TclCmd/array.htm#M15.
| Quote: |
string match ?-nocase? pattern string
-- snip --
[chars] Matches any character in the set given by chars.
-- snip --
|
from http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40.
And that's why set item {[s]}; array unset myarray $item will unset $myarray(s) only, and is different from unset array($item) which unsets the array element with the literal name "[s]". |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|