2012-08-08 24 views
2

我有一個小問題,理解以下命令:需要有關包一些解釋在TCL

package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]] 

在將pkgIndex.tcl, 據我瞭解,當將pkgIndex.tcl其來源和例如,我們包需要HelloWorld 1.0,helloworld.tcl將被採購。我不明白的列表命令

回答

1

包ifneeded命令expects以下輸入:

package ifneeded package version ?script? 

你可以看到,在你的情況下,是的HelloWorld,和版本是1.0。最後,腳本是[list source [文件連接$ dir helloworld.tcl]]。原因列表用於腳本參數需要列表。

7

package ifneeded命令用於註冊(或查詢)如何使包實際上出現在Tcl解釋器中。這是通過評估一個腳本完成的,腳本是在你的例子中用list生成的參數。讓我們解構它。

 
    package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]] 
    ---------------- ========== --- ============================================= 
    command name  package ver   how to make it present, 
         name     result of [list ...] 

到目前爲止,這麼好。現在略微放在一邊:list命令不僅用於製作列表,而且還使保證無替代命令成爲可能。也就是說,它的結果是一個腳本,它由調用命令和它的參數組成,就像它們進入list命令時一樣。

這意味着我們生成的腳本是source somefilename,其中somefilenamefile join的結果。換句話說,你要幾乎同樣的事情:

package ifneeded HelloWorld 1.0 "source $dir/helloworld.tcl" 

除了沒有假設文件名分隔符是/(這是正式的OS的功能,而不是TCL,和file join知道差異)如果$dir碰巧包含空格或其他元字符(比您希望的更常見),則安全。

什麼是$dir?那麼這是pkgIndex.tcl腳本的一個特殊功能,它們(通常)在將dir變量設置爲包含pkgIndex.tcl腳本的目錄的絕對名稱的上下文中進行評估。 (在這一點上,您不能對當前目錄進行假設;屬於主要Tcl程序的用戶,而不是程序包作者)。這使得重定位程序包變得非常容易,因爲您可以將其所有組件文件相對於一個腳本,並將整塊移動到一個塊中。

+0

使用'list'的另一個好處是Tcl隱藏類型系統可以更有效地評估其結果。這裏的差別實際上是無法衡量的,因爲涉及「源代碼」的I/O將主宰數量級。 – 2012-08-08 10:39:57

1

package ifneeded命令期望腳本作爲其最後一個參數。預期腳本(通常意義上)是格式良好的,也就是說,可以被Tcl解析器解析。

在這種情況下的相當標準pkgIndex.tcl,確保的是:不管是什麼「目錄」變量包含在從pkgIndex.tcl代碼處理,腳本應該以這樣的方式來構造的時候,提到後來Tcl分析器在它看到source命令只有一個參數 —不管$dir擴大到包含空格或時髦的字符,如{

輸入list命令。在這裏,它用來構造一個包含兩個元素的列表:字符串「source」和一個包含文件名的字符串(作爲source命令的唯一參數)。現在,當該列表被解釋爲一個腳本(一個字符串)時,Tcl確保字符串表示包含所有需要的引用以消除任何關於空格的歧義等。 這確保瞭解析器稍後解釋我們構建的腳本時,其中的source命令將會收到一個參數。

您可以閱讀更多關於使用list以防止引用問題here的更好書面信息。