'''[http://www.tcl.tk/man/tcl/TclCmd/lappend.htm%|%lappend]''' appends elements to a list. ** Synopsis ** : '''lappend''' ''varName'' ?''value value ...''? ** Description ** `lappend` appends each ''value'' as an [elment] to the list in ''varName'', and also returns the resulting list. `lappend` differs from `[append]` in that values are appended as list elements rather than raw text. `lappend` operates on the specified list in-place, so it is not necessary to assign the results of '''lappend''' to ''varName''. This is why the first argument to `lappend` is the name of a variable rather than the list value itself. It is an error if the value of the variable named ''varName'' is not a list. ======none % set x \{ ;# string that is not a list { % lappend x b ;# treat it as list unmatched open brace in list ====== Examples: ====== lappend auto_path /usr/local/lib/tcl8.5 #Does nothing but fail if listName is not a well-formed list. lappend listName ====== Incorrect usage: ====== #warning: bad code ahead set auto_path [lappend $auto_path /usr/local/lib/tcl8.5] lappend $listName ====== the problem in the set example is not the use of lappend in the [[ ... ]] construct, but the use of '''$auto_path''' as the first argument instead of '''auto_path''' (without the '''$'''). ** List Validation ** Another function of `lappend` is to validate a value as a well-formed list. When invoked with no `value`s, `lappend` simply makes sure that the value of the variable named by ''varName'' is a valid list, and returns it: [RS] 2006-10-01: [jcw] contributed this (for me) surprising [idiom]: ====== lappend var ====== does nothing, but creates ''var'' if it doesn't exist. Similar to, but simpler than: ====== if {![info exists var]} {set var ""} ====== This may however fail if `$var` holds a string that cannot be parsed as a list. [wdb]: It works, but it is some kind of ''dirty trick'' as it is based on some Tcl-internal optimizing located far out of documented behaviour. The greater danger is '''not''' to throw an error. Exemplum gratia, here [lappend] works as you describe: ======none % set a "a {b} c" a {b} c % lappend a a {b} c ====== but here not: ======none % set a "a {b} c" a {b} c % lappend a x a b c x ====== Unintended side effect: element b has "forgotten" its surrounding braces as they are not necessary for identifying b as a list element. I don't think that this will fit to the category [quick'n'dirty] as it is perhaps dirty enough but not quick if you are hunting the resulting bugs on friday afternoon ;-) [Lars H]: Well, if you care about the braces, then apparently you don't merely see the value as a list, and in that case using [lappend] probably isn't the right thing to do (as ''it'' will only respect the list interpretation of the value). [jcw] has also been seen using [append] in the same way, when the value is a more general string. ** Misc ** [jmn] 2008-06-04: I find myself using code like the following very often: ====== if {$item ni $list} { lappend list $item } ====== I know it's not much code.. but It seems to me it'd be neat to have an option so you could instead do something like: ====== lappend -ifmissing list $item ====== jcw: This indicates you're using a list as a set. You could also consider using 8.5's `dict set list $item {}` for a slightly different approach. [RS] 2008-06-04: I just add a convenience proc whenever I need that functionality: ====== proc ladd {_list el} { upvar 1 $_list list if {$el ni $list} {lappend list $el} } ====== ** See also ** [list]: <> Tcl syntax help | Arts and crafts of Tcl-tk programming | Command