It is quite common to find several ways to accomplish the exact same thing. This would be true to some degree of any programming/scripting language.
However, not wishing to seem a bore, I do get the impression that you are not taking in what I am trying to communicate regarding the difference between strings and string lists.
A better understanding of these data structures can save you many problems in the future, though I can say that I do still make such mistakes (such is the ease with which they sometimes get confused).
Taking your latest code example apart :-
Although it cannot be confirmed by simply looking at the statement above, it does give the impression that the original value of the variable text is a string, because it is being split to form a list. The set command overwrites the original string value of text with the list value. Given that it is now a list, you can safely use list commands such as lrange on it :-
Code: Select all
set text [lrange [split $text] 2 end]
Indices for lrange (and other commands) start at zero, so the above statement makes a new list from the 3rd element onwards of text and again overwrites the value of text with this new list. It is STILL a list.
Code: Select all
set text [lrange [split $text] 2 end]
set text "$text :requested by $nick"
This is potentially where things could all go pear shaped. The second statement may well succeed on occasions in generating what you need, yet it does create something that may not have been anticipated. The new list value of text has had string characters attached to it.
There are really two ways to go. Firstly if you want to end up with a normal string :-
Code: Select all
set text [join [lrange [split $text] 2 end]]
set text "$text :requested by $nick"
This is probably the best because it ensures that the value of text is in the same form as it was in the first place. The join command has been used in the first statement to convert the lrange result back into a string. Hence, the second statement simply adds additional characters to form a longer string.
The join command could be alternatively placed as follows :-
Code: Select all
set text [lrange [split $text] 2 end]
set text "[join $text] :requested by $nick"
Secondly, If you definitely need the result to be a list, then you first need to determine if the three words included in ':requested by $nick' are to be three distinct list elements or one single list element. These are the two possibilities :-
Code: Select all
set text [lrange [split $text] 2 end]
lappend text :requested by $nick
Code: Select all
set text [lrange [split $text] 2 end]
lappend text ":requested by $nick"
In reality the problem can get rather more complicated because lists of list and lists of lists of lists etc etc are permitted. That means that the join command wouldn't necessarily create a string. It may create a 'flatter' list. To be fair I would forget this added difficulty until you are confident with the simple case (a normal string OR a flat list of string elements).
Some insight into the sort of problems that can occur can be gained by reading :-
http://www.peterre.info/characters.html