【问题标题】:Tcl: namespace import within namespace evalTcl:命名空间 eval 中的命名空间导入
【发布时间】:2014-10-26 17:48:17
【问题描述】:

我的 Tcl 项目库是这样组织在树中的:

mylib : 基本文件夹(有一些 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 不包含 package by 的条目,这通常表明 tcl 文件中存在一些错误。但是,我可以执行 by.tcl 而不会收到错误消息。如果我的设计有错误,那一定是更微妙的。

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

知道这里出了什么问题吗?

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

您可以通过以下方式重现它:

(1) 下载http://files.ronaldf.eml.cc/stovfl0.tgz并解压到某个目录 (2) 确保 bash(或 zsh)和 tclsh 在你的 PATH 中 (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' 包不见了。

【问题讨论】:

  • 无法复制,抱歉。会不会有其他东西同时发生了变化?
  • 我已经在 8.4 和 8.6 中尝试过,但无法重现;在这两种情况下,我都得到了正确的pkgIndex.tcl。您如何准确地致电pkg_mkIndex?你使用的是哪个版本的 Tcl?
  • 在这种情况下,我将 Tcl 8.5 用于 Mac OSX Snow Leopard。我 cd 到目录,并调用了一个 Tcl 脚本,它执行“pkg_mkIndex .”。当我注释掉命名空间导入时,它可以工作。当我取消注释时,它停止工作。我会尝试在不同的平台上重现它,但由于每个人都保证这应该有效,我怀疑我一定犯了一些严重的错误。我将在这里发布我的发现,如果我真的可以在特定平台上重现它(本周无法访问 Mac),我将上传一个 zip 存档,以便您也可以在您的系统上试用它。
  • 好的,我也有那个版本,所以我可以做一个真正的比较测试。
  • 我刚刚编辑了我的帖子以包含指向可下载示例的链接。

标签: tcl


【解决方案1】:

无论出了什么问题都非常神秘。当我在一个新的空目录中创建以下两个文件时:

# mc.tcl
namespace eval ::mc {
    namespace export dance&sing
}
proc ::mc::dance&sing { {s {Oh Tannenbaum} } } { puts "$s,...." }
package provide mc 1.4
# by.tcl
package require mc
namespace eval ::by {}
proc ::by::execute {} {
    namespace import ::mc::dance&sing
    ::mc::dance&sing "Sushi&more"
}
package provide by 1.1

然后我使用 tclsh8.5(Snow Leopard 系统构建)进入该目录,并发出以下 Tcl 命令:

pkg_mkIndex . *.tcl

然后我得到这个包索引文件,这是正确的

# 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]]

当我使用 Tcl 8.4 或 Tcl 8.6 时,完全相同

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2020-01-14
    • 2010-09-05
    相关资源
    最近更新 更多