Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Variable redirection

60 views
Skip to first unread message

Cecil Westerhof

unread,
May 4, 2018, 6:59:05 AM5/4/18
to
In a script I have:
set dummy "Some information"
set index dummy

I would like to get the value from the variable where index is
pointing to. In this case index contains dummy, so I would like to
get:
"Some Information"

How would I do that? I tried several things, but for example:
puts $$index
gives:
$dummy

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

Harald Oehlmann

unread,
May 4, 2018, 7:22:40 AM5/4/18
to
Am 04.05.2018 um 12:58 schrieb Cecil Westerhof:
> In a script I have:
> set dummy "Some information"
> set index dummy
>
> I would like to get the value from the variable where index is
> pointing to. In this case index contains dummy, so I would like to
> get:
> "Some Information"
>
> How would I do that? I tried several things, but for example:
> puts $$index
> gives:
> $dummy
>

set index [set dummy]

Harald Oehlmann

unread,
May 4, 2018, 7:27:03 AM5/4/18
to
Sorry,
wrong answer.

Here it is:
% set dummy "Some information"
Some information
% set index dummy
dummy
% set $index
Some information

Cecil Westerhof

unread,
May 4, 2018, 7:28:04 AM5/4/18
to
Cecil Westerhof <Ce...@decebal.nl> writes:

> In a script I have:
> set dummy "Some information"
> set index dummy
>
> I would like to get the value from the variable where index is
> pointing to. In this case index contains dummy, so I would like to
> get:
> "Some Information"
>
> How would I do that? I tried several things, but for example:
> puts $$index
> gives:
> $dummy

I found a solution where I could get the value into another variable:
eval "set value $$index"

I could use this, but was wondering if there is a better way.

nemethi

unread,
May 4, 2018, 7:28:38 AM5/4/18
to
Am 04.05.2018 um 12:58 schrieb Cecil Westerhof:
> In a script I have:
> set dummy "Some information"
> set index dummy
>
> I would like to get the value from the variable where index is
> pointing to. In this case index contains dummy, so I would like to
> get:
> "Some Information"
>
> How would I do that? I tried several things, but for example:
> puts $$index
> gives:
> $dummy
>

Instead of

puts $$index

you will have to write

puts [set $index]

--
Csaba Nemethi http://www.nemethi.de mailto:csaba....@t-online.de

Ralf Fassel

unread,
May 4, 2018, 7:30:28 AM5/4/18
to
* Cecil Westerhof <Ce...@decebal.nl>
| In a script I have:
| set dummy "Some information"
| set index dummy
>
| I would like to get the value from the variable where index is
| pointing to. In this case index contains dummy, so I would like to
| get:
| "Some Information"
>
| How would I do that? I tried several things, but for example:
| puts $$index
| gives:
| $dummy

puts [set $index]

See section "Double Indirection" in http://wiki.tcl.tk/1024

HTH
R'

Ralf Fassel

unread,
May 4, 2018, 7:35:20 AM5/4/18
to
* Cecil Westerhof <Ce...@decebal.nl>
| I found a solution where I could get the value into another variable:
| eval "set value $$index"

Don't use 'eval' in this context. It introduces data-dependend problems
if 'index' ever contains something else than a plain variable name.
Use 'set' as explained in the other messages of this thread.

R'

Rich

unread,
May 4, 2018, 8:59:07 AM5/4/18
to
Also, the OP should take note of the fact that in many instances where
he believes he wants pointers, an array will provide the same solution
without the extra trickery.

I.e., for this example: set index(dummy) "Some information"

And if he wants to pass the "array" in/out of procs without using
upvar, then use a "dict" instead.

Cecil Westerhof

unread,
May 4, 2018, 9:44:04 AM5/4/18
to
That was wat I needed. Works like a charm. Thanks.

Cecil Westerhof

unread,
May 4, 2018, 9:59:04 AM5/4/18
to
Yes, I really did not like it. The solution van Harald I do like.

Cecil Westerhof

unread,
May 4, 2018, 10:14:04 AM5/4/18
to
I played some more with it. Was wondering how to do multilevel
redirection. Do not need it at the moment, but you never know. And it
keeps the grey cells busy.

I know have:
set index index2
set index2 index3
set index3 dummy
set dummy "Some Information"

Then you get:
set index -> index2
set $index -> index3
set [set $index] -> dummy
set [set [set $index]] -> "Some Information"

Is that the way to go, or is there a better way?

Rich

unread,
May 4, 2018, 10:50:38 AM5/4/18
to
Cecil Westerhof <Ce...@decebal.nl> wrote:
> I played some more with it. Was wondering how to do multilevel
> redirection.

You'll quickly find the complexity grows exponetionally faster than the
benefits.

> Do not need it at the moment, but you never know. And it keeps the
> grey cells busy.
>
> I know have:
> set index index2
> set index2 index3
> set index3 dummy
> set dummy "Some Information"
>
> Then you get:
> set index -> index2
> set $index -> index3
> set [set $index] -> dummy
> set [set [set $index]] -> "Some Information"
>
> Is that the way to go, or is there a better way?

Your last is the typical way, although often the $index is replaced
with its own set:

set a [set [set [set index]]]

Or, if you want to 'code' the lookup, something like this:

set temp $index
for {set i 0} {$i < 2} {incr i} {
set temp [set [set temp]]
}

The complexity growth is because all of your indirections themselves
need to be variables, so they need non-conflicting names (unless you
want the overlaps) and so you rapidly devolve into managing 286
variables named like pointer_83 and index_24 and so forth.

Cecil Westerhof

unread,
May 4, 2018, 10:59:04 AM5/4/18
to
That is a good tip. Changed the code to work with a dict. Now I have
to wait until I can test it.


The script does enough and it is still under 80 lines. I like tcl. :-D

Cecil Westerhof

unread,
May 4, 2018, 11:28:05 AM5/4/18
to
Cecil Westerhof <Ce...@decebal.nl> writes:

>> Also, the OP should take note of the fact that in many instances where
>> he believes he wants pointers, an array will provide the same solution
>> without the extra trickery.
>>
>> I.e., for this example: set index(dummy) "Some information"
>>
>> And if he wants to pass the "array" in/out of procs without using
>> upvar, then use a "dict" instead.
>
> That is a good tip. Changed the code to work with a dict. Now I have
> to wait until I can test it.

I simulated something and that worked. So probably it is OK. Waiting
till a real situation pops up.

Rich

unread,
May 4, 2018, 11:59:14 AM5/4/18
to
Cecil Westerhof <Ce...@decebal.nl> wrote:
> Cecil Westerhof <Ce...@decebal.nl> writes:
>
>>> Also, the OP should take note of the fact that in many instances
>>> where he believes he wants pointers, an array will provide the same
>>> solution without the extra trickery.
>>>
>>> I.e., for this example: set index(dummy) "Some information"
>>>
>>> And if he wants to pass the "array" in/out of procs without using
>>> upvar, then use a "dict" instead.
>>
>> That is a good tip. Changed the code to work with a dict. Now I have
>> to wait until I can test it.
>
> I simulated something and that worked. So probably it is OK. Waiting
> till a real situation pops up.

Variable indirection is useful, but the low complexity cases are where
it is best used.

I.e., validations are a good spot. Say you've got four input fields,
with appropriate linked variable names, and you want to make sure none
are over 80 characters (this is all made up):

set errors [list]
foreach var {name, street_1, street_2, city} {
if {[string length [set $var]] > 80} {
lappend errors $var
}
}
if {[llength $errors] > 0} {
# handle the validation issues here as appropriate
}

But trying to simulate C pointers rapidly becomes a nightmare of
keeping track of what is happing where for what reason and from where.

Donal K. Fellows

unread,
May 5, 2018, 6:02:47 AM5/5/18
to
On 04/05/2018 11:58, Cecil Westerhof wrote:
> I would like to get the value from the variable where index is
> pointing to.

There are three (good) mechanisms that should be mentioned at this point.

1. Using the one-argument form of [set]:

set dummy "Some information"
set index dummy
puts [set $index]

2. Reworking things to use an array instead:

set data(dummy) "Some information"
set index dummy
puts data($index)

3. Using [upvar 0] to make a local variable alias:

set dummy "Some information"
set index dummy
upvar 0 $index myAlias
puts $myAlias

All of these techniques work reliably without excessive possibility for
surprise (and can be used together if you've go a need).

Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.

Cecil Westerhof

unread,
May 5, 2018, 7:59:05 AM5/5/18
to
First went for 1, but gone to a version of two: using a dict.
0 new messages