As far as I understand, in tcl if you want to pass a named array to a function, you have to access the upper scope of the caller via the upvar
command within the callee body. Is this the only way to pass an array in tcl ?
views:
55answers:
3
+4
A:
There are other ways, like converting it into a list first (via array get
and array set
).
Michael
2010-08-18 14:43:09
+2
A:
As Michael indicated, there are several ways, plus a wiki page that discusses it. Just to have some of that information here, some options are:
By Upvar
proc by_upvar {&arrName} {
upvar 1 ${&arrName} arr
puts arr(mykey)
set arr(myotherkey) 2
}
set myarr(mykey) 1
by_upvar myarr
info exists myarr(myotherkey) => true
- results in changes to the array being seen by the caller
By array get/set
proc by_getset {agv} {
array set arr $agv
puts arr(mykey)
set arr(myotherkey) 2
return [array get arr]
}
set myarr(mykey) 1
array set mynewarr [by_upvar myarr]
info exists myarr(myotherkey) => false
info exists mynewarr(myotherkey) => true
- results in changes to the array being seen by the caller
- similar mechanism can be used to return an array
RHSeeger
2010-08-19 13:32:31
What's up with the amperand in your by_upvar proc? Not Tcl syntax.
glenn jackman
2010-08-20 20:17:03
@glenn jackman: "not tcl syntax"? Nonsense! Everything is tcl syntax :-). Since variable names can be any string and I usually use _ or fooVar (upvar $fooVar foo).
Bryan Oakley
2010-08-21 02:13:53
glenn jackman
2010-08-21 10:41:59
RHSeeger
2010-08-23 00:20:53
+2
A:
If you're only passing in the value of the array, you could pass in a dictionary instead (hint: array get
serializes an array into a dictionary value) and use the dict
command to access values in it. But if you want access to the live value, upvar
is definitely easiest. It's also a very fast technique; it compiles down to an extra traversal of a pointer during variable access after upvar
itself finishes.
Donal Fellows
2010-08-19 20:29:30