我在命名空间“b”中定义了几个函数,我将其导出。然后我将这些函数导入到namespace :: 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。我做错了什么?
答案 0 :(得分: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包含one(two,如果您有贡献的扩展名),并且有许多旧版本可用作扩展包。