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。
我在 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。