TCL中含点变量双重替换报错的解决方案:无需修改点字符获取预期输出
Hey there! I totally get why you're frustrated—TCL's expression parser can be finicky with variable names that have dots. Let's figure out how to get that expected output of 1 without changing your variable name p.txt_bc.
Why the Error Happens
When you run expr $$var, TCL first expands $var to p.txt_bc, turning the command into expr $p.txt_bc. The problem is that TCL's expr treats anything after a $ as an identifier (a variable name for expression contexts), and identifiers can't include dots. So it tries to parse p.txt_bc as $p (variable p) followed by .txt_bc—which makes no sense in an expression, hence the error.
Solution 1: Use set to Fetch the Value Directly (Simplest Approach)
The set command doesn't have the same identifier restriction as expr—it can handle variable names with dots perfectly. Just wrap set $var inside your expr call:
set var "p.txt_bc" set p.txt_bc 1 expr [set $var] ;# Outputs 1
Here's how it works:
set $varevaluates to the value of the variable whose name is stored invar(so it grabs the value1fromp.txt_bc).exprthen takes that value as its input, which is a valid expression, so it returns1as expected.
Solution 2: Use subst to Expand the Variable Reference First
If you prefer to stick closer to your original syntax, you can use subst to fully expand the variable reference before passing it to expr:
set var "p.txt_bc" set p.txt_bc 1 expr [subst "\$$var"] ;# Outputs 1
The \$$var gets expanded by subst to $p.txt_bc, but since we're using subst outside of expr's strict parser, it correctly resolves to the value 1 before expr processes it.
Why These Work (And Your Original Code Didn't)
TCL allows variable names to include dots (they're just strings, after all!), but expr has its own parsing rules for expressions. By using set or subst, we're bypassing expr's identifier parsing and directly fetching the variable's value, which plays nicely with dots in variable names.
内容的提问来源于stack exchange,提问作者Abhishek

