Tcl:找不到包,尽管 auto_path 和 pkgIndex 似乎是正确的

Tcl : Package not found, although auto_path and pkgIndex seem to be correct

我在 Windows 上安装了两个 Tcl 8.4。这是看起来不错的:

(在 tclsh 内部):

% set auto_path
c:/Tcl/lib/tcl8.4 c:/Tcl/lib
% package require csv
0.8

csv 包位于此处:

dir c:\Tcl\lib\tcllib1.15\csv
    06.06.2013  07:52            20.154 csv.tcl
    06.06.2013  07:52               126 pkgIndex.tcl

这是另一个,找不到csv包:

% set auto_path
C:/cygwin64/home/fisrona/gitwrk/vp/lib/tcl8.4 C:/cygwin64/home/fisrona/gitwrk/vp/lib
% package require csv
can't find package csv 

在此安装中,包位于此处:

dir C:\cygwin64\home\fisrona\gitwrk\vp\lib\tcllib1.15\csv
    03.02.2015  08:59            20.154 csv.tcl
    03.02.2015  08:59               126 pkgIndex.tcl

在这两种情况下,auto_path包含lib目录,包位于lib目录下的tcllib1.15/csv。 pkgIndex.tcl 在这两种情况下是相同的,看起来像这样:

if {![package vsatisfies [package provide Tcl] 8.4]} {return}
package ifneeded csv 0.8 [list source [file join $dir csv.tcl]]

这两个安装之间一定有什么不同,导致第二个安装失败。知道可能是什么原因吗?

顺便说一句,两个安装中的 init.tcl(在两种情况下都位于 lib/tcl8.4 中)也是相同的。当然,如果我将 tcllib1.15 目录显式添加到 auto_path,则可以找到该包;但是为什么在第一种情况下找到了包,我不必添加这个目录,但在第二种情况下却没有?

==========

新发现:

good 安装中,当我 require 一个不存在的包,然后再次显示 auto_path 时,我得到以下结果:

% set auto_path
c:/Tcl/lib/tcl8.4 c:/Tcl/lib
% package require xxx
can't find package xxx
% set auto_path
c:/Tcl/lib/tcl8.4 c:/Tcl/lib c:/Tcl/lib/tcllib1.15 c:/Tcl/lib/tcllib1.7 c:/Tcl/lib/tklib0.6 c:/Tcl/lib/vfs1.4.2/template

当需要未知包时,似乎有处理程序启动,并且此处理程序扩展了 auto_path。特别是添加了目录 tcllib1.15,其中包含 csv 目录。如果我在 "bad" 安装中做同样的事情,我会看到:

% package require xxx
can't find package xxx
% set auto_path
C:/cygwin64/home/fisrona/gitwrk/vp/lib/tcl8.4 C:/cygwin64/home/fisrona/gitwrk/vp/lib C:/cygwin64/home/fisrona/gitwrk/vp/lib/tcllib1.7

在这种情况下,只添加了一个目录,而不是包含 csv 文件的目录。

区别似乎是 "unknown package handling" 扩展 auto_path 的方式。我只是想知道,我在哪里可以找到这个处理程序?我在 init.tcl 中找到以下命令:

package unknown [list ::tcl::tm::UnknownHandler [package unknown]]

我在 lib/tcl8.4/tm.tcl 中找到了这个处理程序。这些文件在两个版本中也相同。

看来我必须手动执行 UnknownHandler 以了解发生了什么......我将在这里报告我的发现。

解决了!!!!!!啊,多么愚蠢的错误:

虽然在两个安装中,csv 目录 有一个 pkgIndex.tcl 文件,但在 tcllib1.15 的损坏安装中缺少此文件 目录。

package require csv 时,处理程序 ::tcl::tm::UnknownHandler 被调用,它无法解析它,但随后标准处理程序(由 [ package unknown] 启动。这是一个过程 tclPkgUnknown,在我的 tcl8.4/package.tcl 安装中定义。这个过程搜索在 [=32] 中找到的目录中的所有条目=]。如果其中一个目录有一个子目录,并且在那里也找到了一个 pkgIndex.tcl 文件,该文件中的条目也会被考虑(并且这个目录被添加auto_path).

解决方案:我也必须为我的目录 tcllib1.15 提供一个合适的pkgIndex.tcl。