Version 6 of how do i do $$var - double dereferencing a variable

Updated 2003-03-27 16:46:27

This issue of dereferencing seems to come up frequently enough to deserve a page of tips, suggestions, warnings, etc.

The basic situation is that a user is trying, either intentionally or accidentally, to do pointer like design.

So they end up discovering they need to do something like:

 set a "123"
 set b "3.1415"
 set c "The price of petrol in Peroria"

 foreach var {a b c} {
   puts [set $var]
 }

DKF: More often than not, a solution involving arrays produces a better (more robust, etc.) result:

 set data(a) "123"
 set data(b) "3.1415"
 set data(c) "The price of petrol in Peroria"

 foreach var {a b c} {
    puts $data($var)
 }

Another possibility (more so when splitting things up into procedures) is to use upvar.


TV It's probably worth a page by itself as a subject. A pointer in C language sense is not the same as a indirect reference. Also, associations are not the same as referencing something by name and that is not the same as a pointer in C, in normal language or in for instance a URL. And a function, as clearly the case in tcl is referenced by name, and can be stored as a list.

The simple answer I guess is to use eval:

 set whichvar b
 set b 11
 eval puts $$whichvar

Which leaves a lot of questions about quoting, and preventing the evaluator to perform substitutions (possible through escaping).

A pointer in C, which is rarely seriously usefull in large repetition as in ****something, that would refer to datastructures and referencing them which can work for initializing accessing something in a tree when the structure contains the forward reference as first element, is not the same idea. A pointer in a digital signal processor could be pointing in a subspace of memory not made into the comfortable the_whole_memory_is_one_linear_list which also PC hearts eventually got around to (more or less..), which is like in computer design, where something is a pointer when it is used to point into a memory, which is just the same as an integer memory with access to some address bus.

Though of course in C one would refer to another variable through a pointer, which in various senses is also a variable:

 main()
 {
    int i;
    int *pointer;

     i = 13;
     pointer = &i
     *pointer = 14;
     return *pointer;

}

In Tcl, we have symbolic behaviour of the tcl interpreter which of course at some level and point are implemented at C level (I think it all it, though I could be mistaking) which makes variable referencing by name in runtime different than the above C level.

A nice example is:

 info var prefix_*

which lists all the variables with a certain prefix.

I just tried to list some functions associated with blocks on the bwise canvas:

 (Tcl) 101 % foreach var [info var *bfunc] {eval puts \"$var $\{$var\}\"}
 mapping.bfunc:  set mapping.newstate [fsm_state_map ${mapping.oldstate} ${mapping.input} ] ;   set mapping.output [fsm_output_map ${mapping.oldstate} ${mapping.input} ] 
 Entry1.bfunc: 
 Proc1.bfunc:  set Proc1.out ${Proc1.in} 
 state.bfunc:  set state.out ${state.in} 
 Mon1.bfunc: .mw.c.mon1 del 0.0 end ;.mw.c.mon1 insert end "${Mon1.in} \n" ; .mw.c.mon1 see end

The messy looking (though I'm used to it) string like construction is for the aforementioned quoting and substitution issue. Variable names are considered to end with a dot (.) so I have to enclose them in braces to make them a list first.


Category Tutorial