Tcl lappend 返回意外结果
Tcl lappend returning unexpected results
我正在检查 Tcl tutorial 并且 lappend 运算符返回意外结果。
我在 F5 负载平衡硬件的命令行界面上 运行。这是相关的系统信息:
~ \# cat /proc/version
Linux version 2.6.32-431.56.1.el6.f5.x86_64 (f5cm@build19) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Wed Jun 8 11:41:48 PDT 2016
% puts $tcl_version
8.5
我尝试了所有我能想到的变量分组排列,但我仍然无法得到我期望的结果。似乎有一个缓冲区保存命令的所有结果:'puts' 命令并在 'lappend' 命令中使用它。这是我执行的行。前几个 'puts' 只是为了表明还没有初始化:
% puts $l1
can't read "l1": no such variable
% puts $l2
can't read "l2": no such variable
% puts $l3
can't read "l3": no such variable
% puts $l4
can't read "l4": no such variable
% puts $l5
can't read "l5": no such variable
% set l1 { {item 1} {item 2} {item 3} }
{item 1} {item 2} {item 3}
% set l2 { {item 4} {item 5} {item 6} }
{item 4} {item 5} {item 6}
% set l3 [concat $l1 $l2]
{item 1} {item 2} {item 3} {item 4} {item 5} {item 6}
#things working as expected here
% puts $l3
{item 1} {item 2} {item 3} {item 4} {item 5} {item 6}
#this is where things start to get squirrelly. I would expect this to return the result of $l1 concat with $l2 and the result stored in $l1
% lappend $l1 $l2
{ {item 4} {item 5} {item 6} }
#as you can see, it appears to return the second argument when that argument is a list.
% lappend $l2 $l1
{ {item 1} {item 2} {item 3} }
# $l1 remains unchanged. at the very least, according to the documentation,
# I would expect that second item would be treated as a single entity
# when it is a list, and that the fourth item in '% lappend $l2 $l1' would be $l1
% puts $l1
{item 1} {item 2} {item 3}
#neither $l2 nor $l1 are modified as the result of the 'lappend' command.
% puts $l2
{item 4} {item 5} {item 6}
#more squirrelly-ness. when the arguments being passed are individual, it seems as though the last call to 'puts' is what 'lappend' uses for its first argument. this is confirmed on the last 3 commands below. **strong text**
% lappend $l1 "a" "b" "c"
{ {item 4} {item 5} {item 6} } a b c
% puts $l1
{item 1} {item 2} {item 3}
% lappend "$l1" "$l2"
**{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} }**
% puts $l1
{item 1} {item 2} {item 3}
% puts $l2
{item 4} {item 5} {item 6}
% set l4 [lappend $l1 $l2]
**{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} } { {item 4}
{item 5} {item 6} }**
% puts $l4
{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} } { {item 4}
{item 5} {item 6} }
# confirmed. 'lappend' is using last call to 'puts' as its argument for it's first argument. this can't be intended behavior right?
% puts $l1
{item 1} {item 2} {item 3}
% set l5 [lappend $l2 "a" "b" "c"]
{ {item 1} {item 2} {item 3} } a b c
% puts $l2
{item 4} {item 5} {item 6}
我无法想象这种行为是故意的。
以下是我想象中的效果:
#should return something like [$list1, [$list2]] or something like concat $list1 $list2
% lappend $list1 $list2
#should return each item concatenated to the end of $list1
% lappend $list1 "a" "b" "c"
如果答案是lappend没有修改第一个参数到位,而我必须使用set命令来保存lappend命令的结果,那很好;但是,lappend 命令的行为似乎并不一致。
提前感谢任何help/insight。
lappend $l1 $l2
将 l2 的内容附加到由 l1 的内容命名的变量中。你想要 lappend l1 $l2
,就像你通过 set l1 whatever
设置变量的方式一样,而不是 set $l1 whatever
.
lappend
将变量名作为第一个参数,而不是列表。
案例:
set l1 [list a b c]
lappend $l1 x
puts [set {a b c}]
# returns: x
x
附加到名为 {a b c}
的变量。
相反,使用变量名作为 lappend 的第一个参数:
set l1 [list a b c]
set l2 [list d e f]
lappend l1 {*}$l2
# result: a b c d e f
要记住的一般规则是,如果 Tcl 命令修改其参数,则传递一个变量名。如果 Tcl 命令不修改其参数,则传递值(此规则不适用于数组)。
参考文献:lappend
我正在检查 Tcl tutorial 并且 lappend 运算符返回意外结果。
我在 F5 负载平衡硬件的命令行界面上 运行。这是相关的系统信息:
~ \# cat /proc/version
Linux version 2.6.32-431.56.1.el6.f5.x86_64 (f5cm@build19) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Wed Jun 8 11:41:48 PDT 2016
% puts $tcl_version
8.5
我尝试了所有我能想到的变量分组排列,但我仍然无法得到我期望的结果。似乎有一个缓冲区保存命令的所有结果:'puts' 命令并在 'lappend' 命令中使用它。这是我执行的行。前几个 'puts' 只是为了表明还没有初始化:
% puts $l1
can't read "l1": no such variable
% puts $l2
can't read "l2": no such variable
% puts $l3
can't read "l3": no such variable
% puts $l4
can't read "l4": no such variable
% puts $l5
can't read "l5": no such variable
% set l1 { {item 1} {item 2} {item 3} }
{item 1} {item 2} {item 3}
% set l2 { {item 4} {item 5} {item 6} }
{item 4} {item 5} {item 6}
% set l3 [concat $l1 $l2]
{item 1} {item 2} {item 3} {item 4} {item 5} {item 6}
#things working as expected here
% puts $l3
{item 1} {item 2} {item 3} {item 4} {item 5} {item 6}
#this is where things start to get squirrelly. I would expect this to return the result of $l1 concat with $l2 and the result stored in $l1
% lappend $l1 $l2
{ {item 4} {item 5} {item 6} }
#as you can see, it appears to return the second argument when that argument is a list.
% lappend $l2 $l1
{ {item 1} {item 2} {item 3} }
# $l1 remains unchanged. at the very least, according to the documentation,
# I would expect that second item would be treated as a single entity
# when it is a list, and that the fourth item in '% lappend $l2 $l1' would be $l1
% puts $l1
{item 1} {item 2} {item 3}
#neither $l2 nor $l1 are modified as the result of the 'lappend' command.
% puts $l2
{item 4} {item 5} {item 6}
#more squirrelly-ness. when the arguments being passed are individual, it seems as though the last call to 'puts' is what 'lappend' uses for its first argument. this is confirmed on the last 3 commands below. **strong text**
% lappend $l1 "a" "b" "c"
{ {item 4} {item 5} {item 6} } a b c
% puts $l1
{item 1} {item 2} {item 3}
% lappend "$l1" "$l2"
**{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} }**
% puts $l1
{item 1} {item 2} {item 3}
% puts $l2
{item 4} {item 5} {item 6}
% set l4 [lappend $l1 $l2]
**{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} } { {item 4}
{item 5} {item 6} }**
% puts $l4
{ {item 4} {item 5} {item 6} } a b c { {item 4} {item 5} {item 6} } { {item 4}
{item 5} {item 6} }
# confirmed. 'lappend' is using last call to 'puts' as its argument for it's first argument. this can't be intended behavior right?
% puts $l1
{item 1} {item 2} {item 3}
% set l5 [lappend $l2 "a" "b" "c"]
{ {item 1} {item 2} {item 3} } a b c
% puts $l2
{item 4} {item 5} {item 6}
我无法想象这种行为是故意的。
以下是我想象中的效果:
#should return something like [$list1, [$list2]] or something like concat $list1 $list2
% lappend $list1 $list2
#should return each item concatenated to the end of $list1
% lappend $list1 "a" "b" "c"
如果答案是lappend没有修改第一个参数到位,而我必须使用set命令来保存lappend命令的结果,那很好;但是,lappend 命令的行为似乎并不一致。
提前感谢任何help/insight。
lappend $l1 $l2
将 l2 的内容附加到由 l1 的内容命名的变量中。你想要 lappend l1 $l2
,就像你通过 set l1 whatever
设置变量的方式一样,而不是 set $l1 whatever
.
lappend
将变量名作为第一个参数,而不是列表。
案例:
set l1 [list a b c]
lappend $l1 x
puts [set {a b c}]
# returns: x
x
附加到名为 {a b c}
的变量。
相反,使用变量名作为 lappend 的第一个参数:
set l1 [list a b c]
set l2 [list d e f]
lappend l1 {*}$l2
# result: a b c d e f
要记住的一般规则是,如果 Tcl 命令修改其参数,则传递一个变量名。如果 Tcl 命令不修改其参数,则传递值(此规则不适用于数组)。
参考文献:lappend