需要一些关于TCL包的解释

cof*_*eak 2 tcl

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

package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
Run Code Online (Sandbox Code Playgroud)

在pkgIndex.tcl中,我知道当源pkgIndex.tcl时,例如,我们打包需要HelloWorld 1.0,helloworld.tcl将被获取.我不明白列表命令......

Don*_*ows 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,其中somefilename的结果是file join.换句话说,你得到的几乎是:

package ifneeded HelloWorld 1.0 "source $dir/helloworld.tcl"
Run Code Online (Sandbox Code Playgroud)

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

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