Tcl 列表中的变量替换
Variable substitution in a list in Tcl
我正在尝试替换列表中的变量:
% set a 1
1
% set b {1 $a}
1 $a
%
% set a 1
1
% set b [list 1 $a]
1 1
当我使用花括号 {}
来定义列表时,变量 'a' 不会被其值替换,但在使用 list
的情况下会被替换。
使用 {}
定义的列表时如何替换变量的值?
% set a 1
1
% subst {1 $a}
1 1
% set b [subst {1 $a}]
1 1
但大多数 Tcl:ers 实际上更喜欢在创建带有替换的列表值时使用 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
How do I substitute a variable's value when using a list defined with {}?
简而言之,你没有。
{}
真正所做的是定义一个未替换的字符串。可以将其解释为列表,但也可以是其他内容,例如脚本。所有这些都是 Tcl 的基本性质的一部分。
如果你想替换变量,你可以使用不同类型的引号,或者你 运行 通过 subst
的结果(它被定义为处理字符串)。现在最常用于列表的“引用”是 list
命令,因为它可以正确保留元素边界。
我想可以通过各种字符串操作来创建一个可以 post 处理字符串的命令,但它会很慢而且很复杂:
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}
似乎在这个简单的案例中有效,但我不想保证它实际上 正确。 (毕竟,它使用的是 string map
and regexp
and subst
;可能会出什么问题? ) 正确使用 list
好吗?
我正在尝试替换列表中的变量:
% set a 1
1
% set b {1 $a}
1 $a
%
% set a 1
1
% set b [list 1 $a]
1 1
当我使用花括号 {}
来定义列表时,变量 'a' 不会被其值替换,但在使用 list
的情况下会被替换。
使用 {}
定义的列表时如何替换变量的值?
% set a 1
1
% subst {1 $a}
1 1
% set b [subst {1 $a}]
1 1
但大多数 Tcl:ers 实际上更喜欢在创建带有替换的列表值时使用 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
How do I substitute a variable's value when using a list defined with {}?
简而言之,你没有。
{}
真正所做的是定义一个未替换的字符串。可以将其解释为列表,但也可以是其他内容,例如脚本。所有这些都是 Tcl 的基本性质的一部分。
如果你想替换变量,你可以使用不同类型的引号,或者你 运行 通过 subst
的结果(它被定义为处理字符串)。现在最常用于列表的“引用”是 list
命令,因为它可以正确保留元素边界。
我想可以通过各种字符串操作来创建一个可以 post 处理字符串的命令,但它会很慢而且很复杂:
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}
似乎在这个简单的案例中有效,但我不想保证它实际上 正确。 (毕竟,它使用的是 string map
and regexp
and subst
;可能会出什么问题? ) 正确使用 list
好吗?