List Tcl中列表中的变量替换

List Tcl中列表中的变量替换,list,tcl,variable-substitution,List,Tcl,Variable Substitution,我试图替换列表中的变量: % set a 1 1 % set b {1 $a} 1 $a % % set a 1 1 % set b [list 1 $a] 1 1 当我使用大括号{}来定义列表时,变量“a”不会被其值替换,但在使用列表的情况下,它会被替换 使用用{}定义的列表时,如何替换变量的值 % set a 1 1 % subst {1 $a} 1 1 % set b [subst {1 $a}] 1 1 但是大多数Tcl:er实际上更喜欢在创建带有

我试图替换列表中的变量:

% set a 1  
1  
% set b {1 $a}  
1 $a  
%  
% set a 1  
1  
% set b [list 1 $a]  
1 1  
当我使用大括号
{}
来定义列表时,变量“a”不会被其值替换,但在使用
列表的情况下,它会被替换

使用用
{}
定义的列表时,如何替换变量的值

% set a 1
1
% subst {1 $a}
1 1
% set b [subst {1 $a}]
1 1
但是大多数Tcl:er实际上更喜欢在创建带有替换的列表值时使用
list
,比如在第二次尝试中:

% set b [list 1 $a]
原因之一是
subst
不会在值中保留列表结构:

% set a {a b}
a b
% set b [subst {1 $a}]
1 a b
% set b [list 1 $a]
1 {a b}
另一种可能是使用双引号代替大括号;这也不会保留列表结构

% set b "1 $a"
1 a b
文件: , , ,

使用{}定义的列表时,如何替换变量的值

简而言之,你没有

{}
真正做的是定义一个未替换的字符串。可以将其解释为列表,但也可以是其他内容,例如脚本。这是Tcl的基本性质的一部分,它就是所有这些东西

如果要替换变量,可以使用不同类型的引号,或者通过
subst
(定义为处理字符串)运行结果。现在最常用于列表的“引用”是
list
命令,因为它可以正确地保留元素边界

我认为可以使用各种字符串操作来生成一个命令,该命令可以根据需要对字符串进行后期处理,但这样做既慢又复杂:

proc substList {string} {
    # Add backslashes in front of metacharacters
    set safer [string map {\\ \\\\ [ \\[ ] \\]} $string]
    # Convert variable mentions to our “safe” version
    regsub -all {\$\w+} $safer {[list &]} tmpl
    # Do the substitutions in the caller's context
    tailcall subst $tmpl
}
快速测试:

% set a "1 2 3"
1 2 3
% set b {x $a}
x $a
% substList $b
x {1 2 3}
在这个简单的案例中似乎有效,但我不想保证它实际上是正确的。(毕竟,它使用的是
字符串映射
regexp
subst
;可能会出什么问题?)只要正确使用
列表
,好吗