[[Explain what's meant.]] When programming, one has several choices for getting information into a [proc]edure: * pass an argument value at invocation * pass a variable reference (usable via uplevel or upvar) at invocation * access a local variable * access a non-local (global, environment, outside the frame) variable * request input from the user or from a file/socket/etc. In [Tcl], variables containing strings (whether in list, handle, or normal string format) are typically passed by value. This means that the called procedure never really knows the name of the variable containing the value - and thus it cannot directly modify that value. Instead, most Tcl scripting looks like: set val [lindex $val 2] In other words, the value of a variable changes after the command has calculated a new value. Entire arrays, however, are not currently able to be passed by value to a Tcl procedure. This is due to Tcl currently passing only 'string' type data as arguments, and arrays not having a simple string notation for their value. Instead, there are two choices for passing [array]s both "into" and "out of" [proc]-s: * serialization (generally converting the values of an array into a list with "array get ...") * local proxying of an external variable by use of [upvar] or occasionally [uplevel] [[Examples]] * Create an array from pairlist: ''array set A {city Hamilton state TX zip 34567}'' * Serialize an array to pairlist: ''set L [[array get A]]'' * Copying an array: ''array set B [[array get A]]'' [[but we have to show explicitly how this relates to proc-to-proc communication]] Example proc top {} { array set thisarr { en "Hi everybody" de "Guten Morgen allerseits" } puts "top: english=$thisarr(en)" puts "top: german=$thisarr(de)" set newarrlist [bottom [array get thisarr]] array unset thisarr array set thisarr $newarrlist puts "top: latin=$thisarr(la)" } proc bottom {arrlist} { array set thatarr $arrlist puts "bottom: english=$thatarr(en)" puts "bottom: german=$thatarr(de)" set thatarr(la) "Salvete omnes" return [array get thatarr] } Note that the cost of [[array get]] and [[array set]] is not as bad as it looks. Because in the implementation objects are reference-counted and the intermediate is represented as a real list, the content of the array keys and values are never actually copied. Only the array structure itself is recreated by [[array set]]. ---- '''Removing keys with empty values from an array:''' Note that the array name is passed in, associated with local variable ''arr''. The unsetting of elements with empty value, done in ''arr'', in fact happens in the caller's original array. proc cleanArray arrName { upvar 1 $arrName arr foreach key [array names arr] { if {$arr($key) == ""} {unset arr($key)} } } [KBK] (16 April 2002) - In Tcl 8.3 and beyond, it's much faster to say, simply: array unset arr rather than looping through the result of [[array names]]. In earlier versions, you can say unset arr array set arr {} but that has the disadvantage of messing up any traces that are extant on the array. [RS]: Indeed, but this clears the whole array - the specified task was to remove only those elements which have empty values. ---- In 2005, we need to update this with a discussion of [dict]s. ---- [Category Tutorial]