2

我在理解以下命令时遇到了一点问题:

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

在 pkgIndex.tcl 中,我知道当 pkgIndex.tcl 被采购时,例如,我们打包需要 HelloWorld 1.0 , helloworld.tcl 将被采购。我不明白 list 命令...

4

3 回答 3

7

package ifneeded命令用于注册(或查询)如何使包实际出现在 Tcl 解释器中。这是通过评估脚本来完成的,该脚本是list您的示例中生成的参数。让我们解构它。

   package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
   ---------------- ========== --- ===================== =========================
    命令名称包验证如何使其呈现,
                      [list ...] 的名称结果

到目前为止,一切都很好。现在,顺便说一句:该list命令不仅用于制作列表,而且还制作保证无替换的命令。也就是说,它的结果是一个脚本,其中包含对命令及其参数的调用,与它们进入list命令时完全相同。

这意味着我们正在生成一个脚本,即.的结果在source somefilename哪里。换句话说,您得到的几乎与以下内容相同:somefilenamefile join

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

除了没有假设文件名分隔符是/(这是操作系统的正式功能,而不是 Tcl,并且file join知道差异)并且如果$dir碰巧包含空格或其他元字符是安全的(比您可能更常见)希望)。

是什么$dir?好吧,这是pkgIndex.tcl脚本的一个特殊功能,它们(通常)在将dir变量设置为包含pkgIndex.tcl脚本的目录的绝对名称的上下文中进行评估。(此时您不能假设当前目录;它属于主 Tcl 程序的用户,而不是包作者。)这使得重新定位一个包变得非常容易,因为您可以放置​​它的所有组件相对于一个脚本的文件,只需将整个文件移动到一个块中。

于 2012-08-08T10:38:26.307 回答
1

package ifneeded命令需要一个脚本作为其最后一个参数。脚本被期望(在常识中)格式正确,也就是说,可以被 Tcl 解析器解析。

在这种相当标准pkgIndex.tcl的情况下,要确保的是:无论“dir”变量在pkgIndex.tcl处理代码时包含什么,都应该以这样的方式构造脚本,以便稍后 Tcl 解析器在它是只有一个参数source的命令——无论是否扩展为包含空格或时髦的字符等。$dir{

输入list命令。在这里,它用于构造两个元素的列表:字符串“source”和包含文件名的字符串(作为该source命令的唯一参数)。现在,当该列表被解释为脚本(字符串)时,Tcl 确保字符串表示包含所有需要的引用,以消除有关空格等的任何歧义。这确保了当解析器稍后解释我们构造的脚本时,其中的source命令将接收正是一个论点。

您可以在此处阅读更多关于使用list以防止引用问题的更好的书面信息。

于 2012-08-08T10:40:47.170 回答
1

package ifneeded命令需要以下输入:

package ifneeded package version ?script?

可以看到,在你的案例中,是HelloWorld,版本是1.0。最后,脚本是[list source [file join $dir helloworld.tcl]]。使用列表的原因是脚本参数需要一个列表。

于 2012-08-08T09:01:10.137 回答