Reputation: 35
I am trying to understand the difference between TCL arrays and TCL dictionary
There I get a statement :- "TCL array is a collection of variables while TCL dictionary is a collection of values"
Can somebody explain what it actually means. Programming example to understand the same will be great
Thanks
Upvotes: 1
Views: 448
Reputation: 137787
One of the big differences is that you can trace add variable
on an element of an array, whereas you can pass a dictionary into a procedure and return it from a procedure without needing to fiddle around with upvar
or array get
/array set
.
proc didSetOnVarElement {name1 name2 op} {
puts "did $op on ${name1}($name2)"
}
trace add variable x(a) write didSetOnVarElement
set x(a) 1
set x(b) 2
incr x(a)
# Try comparing the output of that with what you get when you set a trace on the whole of x
Tracing array elements can be really useful, especially in Tk. So can passing things back and forth cheaply. You can't have them together though: values don't have identity in Tcl, whereas variables do (and it is exactly that identity — that name — that makes them modifiable and traceable entities while preventing them from being passed around trivially).
Upvotes: 1
Reputation: 247210
In addition to Chris's excellent answer:
A dictionary can be passed to a proc as a value
proc printItByValue {value} {
puts $value
}
set myDict [dict create a 1 b 2 c 3] ;# just another way to create a dict
printItByValue $myDict ;# => a 1 b 2 c 3
An array must be passed to a proc differently:
array set myArray {a 1 b 2 c 3} ;# just another way to populate an array
printItByValue $myArray ;# error as shown by Chris
printItByValue myArray ;# only prints the string "myArray"
We could extract the arrays contents and pass that to a proc as a list:
proc printArrayByValue {arrayContents} {
array set localArray $arrayContents
parray localArray
}
printArrayByValue [array get myArray]
localArray(a) = 1
localArray(b) = 2
localArray(c) = 3
parray
is a handy utility proc to pretty-print an array.
Or, we can use the upvar
command to link the passed variable name to the caller's stackframe.
proc printArrayByName {varName} {
upvar 1 $varName localArray
parray localArray
}
printArrayByName myArray ;# same output as above
Note that these procs print out the array using the local name. To get the array to print with the same name, we can do this tricky thing to link the local variable to the caller's variable with the same name:
proc printArrayByName {varName} {
upvar 1 $varName $varName
parray $varName
}
printArrayByName myArray ;# same output as above
myArray(a) = 1
myArray(b) = 2
myArray(c) = 3
Upvotes: 0
Reputation: 1873
With an array, these are actually three separate variables.
set my_array(a) 1
set my_array(b) 2
set my_array(c) 3
Each variable exists separately:
info exists my_array(a) --> 1
info exists my_array(b) --> 2
info exists my_array(c) --> 3
puts "$my_array(a) $my_array(b) $my_array(c)" --> 1 2 3
The name my_array
is also recognized to exist, but is actually a special name for the collection of the three individual variables. It's not really a regular variable that has its own value.
info exists my_array --> 1
puts $my_array --> can't read "my_array": variable is array
With a dictionary, there is one variable. The value of the variable represent the key/value pairs.
set my_dict "a 1 b 2 c 3"
info exists my_dict --> 1
info exists my_dict a --> wrong # args: should be "info exists varName"
puts $my_dict --> {a 1 b 2 c 3}
dict keys $my_dict --> {a b c}
dict get $my_dict a --> 1
dict values $my_dict --> {1 2 3}
In this example, the value of my_dict
is {a 1 b 2 c 3}
. You can pass $my_dict
as an argument to a proc and the value is used by the proc. You can also return a dict from a proc. You cannot do that with an array in the same way.
Upvotes: 1