2016-03-08 71 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