ceeeb
ceeeb

Reputation: 13

Variable substitution in TCL within curly brace

I'm having a problem where variables are in curly brace.I am trying to perform a variable substitution within curly braces which I understand is not feasible directly in TCL.But if there are other methods to resolve this? because I see the samiliar question in website that the answer is use list [] and others. But I want to countinue use curly brace, could someone can help me to resolve the question?

set top_design a
puts $top_design
puts {aaa %top_design}

output :

 a
 aaa %top_design

so how to display the subtitute of top_design in second puts.

Upvotes: 1

Views: 515

Answers (3)

Donal Fellows
Donal Fellows

Reputation: 137567

In Tcl 8.7, you'll be able to do this:

set top_design a
puts $top_design
set input {aaa %top_design}

puts [regsub -all -command {%(\w+)} $input {apply {{- varName} {
    upvar 1 $varName var
    # Ignore case where variable doesn't exist
    return $var
}}}]

The key thing is that %top_design isn't very special at all to Tcl code; the % symbol is only meaningful in a few contexts (format, clock, expr, and Tk's bind). For it to have any other meaning, you have to apply that meaning yourself. That gets much easier with regsub -command (a new feature in 8.7) since that lets you use a command to generate the substitution within a regsub; that pairs well with apply though you could use a procedure instead. In earlier versions, such substitutions required non-trivial quoting and subst; I always found those things difficult to write correctly.

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246764

Aside from the % typo, you're looking for the subst command:

set top_design a
puts {aaa $top_design}          ;# => aaa $top_design
puts [subst {aaa $top_design}]  ;# => aaa a

There are options to subst so that you have control over which things get substituted:

% puts [subst {aaa $top_design\n[clock seconds]}]
aaa a
1666273294
% puts [subst -nocommands -nobackslashes {aaa $top_design\n[clock seconds]}]
aaa a\n[clock seconds]

Upvotes: 1

Krzysztof Jurga
Krzysztof Jurga

Reputation: 1

I think that you have messed up a little while forming the question. In Tcl, { and } have special meaning, you can simpy say that this is an escape sequence or a list - depending on where it is used.

Let's see the following simple example:

set v1  aaa
set v2  bbb
set vres1 {$v1 $v2}
set vres2 "\{$v1 $v2\}"
set vres3 "\{\$v1 \$v2\}"
set vres4 {{$v1 $v2}}

This will result in the following output:

% set vres1 {$v1 $v2}
$v1 $v2
% set vres2 "\{$v1 $v2\}"
{aaa bbb}
% set vres3 "\{\$v1 \$v2\}"
{$v1 $v2}
% set vres4 {{$v1 $v2}}
{$v1 $v2}

For vres1, you have variables not evaluated as {} were used as an escape sequence. For vres2, braces are escaped so are treated as a standard character, thus "" are needed to properly set all the characters as one argument for set command. Note that v1 and v2 are evaluated here as {} are not escape characters but characters that we are just saving in variable. For vres3, we did manual escaping of braces and $ so that variables are not evaluated and braces are part of the string. For vres4, first set of braces are escaping the second set and also $.

Now I guees, that you already have something like vres3 or vres4 and you want to get the values of the variables in braces. When you have nested variables, you should use the eval command like below:

% eval set out1 \"$vres1\"
aaa bbb
% eval set out2 \"$vres2\"
{aaa bbb}
% eval set out3 \"$vres3\"
{aaa bbb}
% eval set out4 \"$vres4\"
{aaa bbb}

I hoped it helped in your issue!

[Ufff, my first answer!]

Upvotes: 0

Related Questions