2016-03-08 47 views
1

我遇到了一个场景,我需要使用参数扩展命令format。使用Tcl8.5,我使用的是{*},它的工作原理类似于魅力。带格式命令的参数扩展

但是,用Tcl8.4,我试过eval。但是,没有运气。

% set x "This is stackoverflow" 
This is stackoverflow 
% format "%10s %5s %20s" {*}$x 
     This is  stackoverflow 
% eval format "%10s %5s %20s" $x 
    %5s 
% eval list format "%10s %5s %20s" $x 
format %10s %5s %20s This is stackoverflow 
% eval [list format "%10s %5s %20s" $x] 
not enough arguments for all format specifiers 
% eval format "%10s %5s %20s" [list $x] 
     %5s 
% eval format "%10s %5s %20s" [concat $x] 
     %5s 

这是什么错误?

+0

你都知道,8.4不支持? –

回答

3

查看文章eval and double substitution的一部分。

正确的方法是:

eval "format {%10s %5s %20s} $x" 

这里eval不能连接任何参数,因此得到什么的解释是取代形式:format {%10s %5s %20s} This is stackoverflow。您当然可以使用eval "format \"%10s %5s %20s\" $x",但我更喜欢避免在可能的情况下使用反斜杠进行转义。


eval format "%10s %5s %20s" $x 

是错误的,因为EVAL首先连接了字符串在一起,所以你最终:

eval format %10s %5s %20s $x 

这就好比说format %10s %5s %20s $x和这就是为什么你会得到你得到了什么)


eval list format "%10s %5s %20s" $x 

变为:

eval list format %10s %5s %20s $x 

这就好比说list format %10s %5s %20s $x并没有什么让format真正做一些事情。


eval [list format "%10s %5s %20s" $x] 

是在正确的方向,但$x是没有得到扩大,使你在做format "%10s %5s %20s" $x


其他人只能把$x陷入更深的列表,或者在不改变这种情况下,任何东西。

1

如果编写诸如eval等concat-and-evaluate命令的调用的方式尚不清楚,那么通常用concat代替命令以查看即将被评估的内容通常是有帮助的。 concat format "%10s %5s %20s" $x而不是eval format "%10s %5s %20s" $x

这些形式弄平格式化字符串,使得所述第二格式指定符的第一值的参数(前两个是相等的,$x是一个平面列表并且因此相同[concat $x]):

concat format "%10s %5s %20s" $x 
# -> format %10s %5s %20s This is stackoverflow 
concat format "%10s %5s %20s" [concat $x] 
# -> format %10s %5s %20s This is stackoverflow 
concat format "%10s %5s %20s" [list $x] 
# -> format %10s %5s %20s {This is stackoverflow} 

这种形式还插入不属于有一个list命令:

concat list format "%10s %5s %20s" $x 
# -> list format %10s %5s %20s This is stackoverflow 

这种形式保留格式化字符串列表结构,但不幸的是还保留的$x列表结构:

concat [list format "%10s %5s %20s" $x] 
# -> format {%10s %5s %20s} {This is stackoverflow} 

这两种形式做正确的事情:他们保留格式字符串,但扁平化的参数列表:

concat "format {%10s %5s %20s} $x" 
# -> format {%10s %5s %20s} This is stackoverflow 
concat [list format {%10s %5s %20s}] $x 
# -> format {%10s %5s %20s} This is stackoverflow 

文档:concatevalformatlist

3

8.4成语是使用linsert创建要评估的命令

set x "This is stackoverflow" 
set args [split $x] 
set cmd [linsert $args 0 format "%10s %5s %20s"] 
set formatted [eval $cmd] 

,或者嵌套在一行

set formatted [eval [linsert [split $x] 0 format "%10s %5s %20s"]] 
+0

谢谢Glenn先生..这很有帮助。 – Dinesh