1

我在导出的命名空间“b”中定义了几个函数。然后我将这些函数导入命名空间 ::x::Y,因此:

namespace eval ::x::y "namespace import fun"

一段时间后,我这样做:

namespace eval ::x::y fun

有趣的地方:

proc fun {} {
   puts "[namespace current]"
   uplevel {puts "[namespace current]"}
}

打印的内容是:

::b
::x::y

我想要和需要的是在 ::x::y 中而不是在 ::b 中发生“乐趣”。我究竟做错了什么?

4

1 回答 1

1

Tcl 的命名空间不是这样工作的。每个过程都与一个名称空间相关联,该名称空间就是其名称所在的名称空间。当您使用namespace import时,该过程的别名被放置在导入命名空间中,该命名空间允许从另一个命名空间调用该过程,但该过程本身仍保留在其原始命名空间中并在该命名空间中执行。

如果您想知道调用者的命名空间,请使用uplevel namespace current(或uplevel 1 {namespace current}使用稍微复杂但更高效的版本)。这实际上并没有告诉您哪个名称空间包含用于调用该过程的命令;为此,您需要这个怪物(在调用的命令中):

namespace qualifiers [uplevel 1 [list namespace which [lindex [info level 0] 0]]]

当然,如果你需要这么多,那么你可能做错了什么。(这很明显,考虑到获取信息所需的代码长度和复杂性。)

特别是,如果你假装用它做面向对象,请停下来使用一个真实的对象系统,它可以正确处理所有棘手的细节。Tcl 8.6.0 包括一个两个,如果您有贡献的扩展),并且有许多旧版本可用作扩展包。

于 2012-12-27T10:27:13.623 回答