Tcl:命名空间eval中的命名空间导入

Tcl:命名空间eval中的命名空间导入,tcl,Tcl,我的Tcl项目库组织在如下树中: bash ./run-it.sh mylib:Base文件夹(有一些Tcl)文件 mylib/foo、mylib/bar(包含一些其他Tcl文件的子目录) 特别是,我有mylib/foo/mc.tcl,它提供了一个带有名称的包mc # File mc.tcl namespace eval ::mc { namespace export dance&sing } proc ::mc::dance&sing { {s {Oh Tannenb

我的Tcl项目库组织在如下树中:

bash ./run-it.sh
mylib:Base文件夹(有一些Tcl)文件
mylib/foo、mylib/bar(包含一些其他Tcl文件的子目录)

特别是,我有mylib/foo/mc.tcl,它提供了一个带有名称的包mc

# File mc.tcl
namespace eval ::mc {
    namespace export dance&sing
}
proc ::mc::dance&sing { {s {Oh Tannenbaum} } } { puts "$s,...." }
package provide mc 1.4
这很有效。现在我添加了mylib/bar/by.tcl,提供了一个名称空间:by并使用包mc:

# file by.tcl
package require mc
namespace eval ::by {}
proc ::by::execute {} {
    ::mc::dance&sing "Sushi&more"
}
package provide by 1.1
到目前为止,一切都是广告宣传的。现在我想(作为练习)通过从:mc导入导出的符号来更改by.tcl。这是找我的零钱:

namespace eval ::by {
    namespace import ::mc::dance&sing
}
在通过pkg_mkIndex运行修改后的文件时,我发现生成的pkgIndex.tcl不包含包by的条目,这通常表明tcl文件中存在错误。但是,我可以执行by.tcl而不会收到错误消息。如果在我的设计中有一个bug,它一定是更微妙的

我的TCLLIBPATH环境变量只包含基本文件夹mylib(当然是绝对路径)。这应该不是问题,因为包的文件是递归查找的

知道这里出了什么问题吗

我添加了一个重现问题的示例

以下是您如何复制它:

(1) 下载并解压缩到某个目录 (2) 确保bash(或zsh)和tclsh在您的路径中 (3) 将cd放入已将所有内容解压缩到的目录中,并按如下方式运行:

bash ./run-it.sh
您应该会看到类似以下内容的输出:

pkg_mkIndex for directory ....stovfl0/mylib/foo
pkg_mkIndex for directory ....stovfl0/mylib/bar
(4) cat mylib/bar/pkgIndex.tcl


你会注意到,包“by”不见了。

任何出错的地方都很神秘。在新的空目录中创建以下两个文件时:

# mc.tcl
namespace eval ::mc {
    namespace export dance&sing
}
proc ::mc::dance&sing { {s {Oh Tannenbaum} } } { puts "$s,...." }
package provide mc 1.4
然后我使用tclsh8.5(雪豹系统构建)进入该目录,并发出以下Tcl命令:

pkg_mkIndex . *.tcl
然后我创建了这个包索引文件,这是正确的


当我使用Tcl 8.4或Tcl 8.6时,我得到了完全相同的结果。

无法复制,抱歉。是否有其他东西同时发生了变化?我在8.4和8.6中尝试过,但我无法复制;在这两种情况下,我都得到了正确的
pkgIndex.tcl
。您到底是如何调用pkg\u mkIndex?您使用的是什么版本的Tcl?在本例中,我使用的是MacOSXSnowLeopard的TCL8.5。我将cd复制到目录,并调用了一个执行“pkg_mkIndex”的Tcl脚本。当我注释掉名称空间导入时,它就工作了。当我取消注释它时,它停止工作。我将尝试在另一个平台上复制它,但由于每个人都确信这会起作用,我怀疑我一定犯了一些严重的错误。我会在这里发布我的发现,如果我真的可以在特定平台上复制它(本周无法访问Mac),我会上传一个zip存档,这样你也可以在你的系统上试用。好的,我也有这个版本,所以我可以做一个真正的比较测试。我刚刚编辑了我的帖子,添加了一个可下载示例的链接。
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded by 1.1 [list source [file join $dir by.tcl]]
package ifneeded mc 1.4 [list source [file join $dir mc.tcl]]