我在理解以下命令时遇到了一点问题:
package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
在 pkgIndex.tcl 中,我知道当 pkgIndex.tcl 被采购时,例如,我们打包需要 HelloWorld 1.0 , helloworld.tcl 将被采购。我不明白 list 命令...
我在理解以下命令时遇到了一点问题:
package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
在 pkgIndex.tcl 中,我知道当 pkgIndex.tcl 被采购时,例如,我们打包需要 HelloWorld 1.0 , helloworld.tcl 将被采购。我不明白 list 命令...
该package ifneeded
命令用于注册(或查询)如何使包实际出现在 Tcl 解释器中。这是通过评估脚本来完成的,该脚本是list
您的示例中生成的参数。让我们解构它。
package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]] ---------------- ========== --- ===================== ========================= 命令名称包验证如何使其呈现, [list ...] 的名称结果
到目前为止,一切都很好。现在,顺便说一句:该list
命令不仅用于制作列表,而且还制作保证无替换的命令。也就是说,它的结果是一个脚本,其中包含对命令及其参数的调用,与它们进入list
命令时完全相同。
这意味着我们正在生成一个脚本,即.的结果在source somefilename
哪里。换句话说,您得到的几乎与以下内容相同:somefilename
file join
package ifneeded HelloWorld 1.0 "source $dir/helloworld.tcl"
除了没有假设文件名分隔符是/
(这是操作系统的正式功能,而不是 Tcl,并且file join
知道差异)并且如果$dir
碰巧包含空格或其他元字符是安全的(比您可能更常见)希望)。
是什么$dir
?好吧,这是pkgIndex.tcl
脚本的一个特殊功能,它们(通常)在将dir
变量设置为包含pkgIndex.tcl
脚本的目录的绝对名称的上下文中进行评估。(此时您不能假设当前目录;它属于主 Tcl 程序的用户,而不是包作者。)这使得重新定位一个包变得非常容易,因为您可以放置它的所有组件相对于一个脚本的文件,只需将整个文件移动到一个块中。
该package ifneeded
命令需要一个脚本作为其最后一个参数。脚本被期望(在常识中)格式正确,也就是说,可以被 Tcl 解析器解析。
在这种相当标准pkgIndex.tcl
的情况下,要确保的是:无论“dir”变量在pkgIndex.tcl
处理代码时包含什么,都应该以这样的方式构造脚本,以便稍后 Tcl 解析器在它是只有一个参数source
的命令——无论是否扩展为包含空格或时髦的字符等。$dir
{
输入list
命令。在这里,它用于构造两个元素的列表:字符串“source”和包含文件名的字符串(作为该source
命令的唯一参数)。现在,当该列表被解释为脚本(字符串)时,Tcl 确保字符串表示包含所有需要的引用,以消除有关空格等的任何歧义。这确保了当解析器稍后解释我们构造的脚本时,其中的source
命令将接收正是一个论点。
您可以在此处阅读更多关于使用list
以防止引用问题的更好的书面信息。
package ifneeded命令需要以下输入:
package ifneeded package version ?script?
可以看到,在你的案例中,包是HelloWorld,版本是1.0。最后,脚本是[list source [file join $dir helloworld.tcl]]。使用列表的原因是脚本参数需要一个列表。