manju sharma
manju sharma

Reputation: 35

TCL : array is a collection of variables

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

Answers (3)

Donal Fellows
Donal Fellows

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

glenn jackman
glenn jackman

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

Chris Heithoff
Chris Heithoff

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

Related Questions