这是问题的简化情况。我正在尝试将过程复制到名称空间,以便它将使用名称空间自己的上下文。使用导入不起作用(可能是因为它只是创建别名)请参阅下面的代码:
proc me_namespace {} {
puts "namespace is:[namespace current]"
puts "called namespace is:[uplevel 1 namespace current ]"
}
namespace eval foo {} {
me_namespace
puts "Now import"
namespace import ::::me_namespace
me_namespace
}
代码输出为:
namespace is:::
called namespace is:::foo
Now import
namespace is:::
called namespace is:::foo
namespace is:::foo
理想情况下,复制后的 proc me_namespace 第一行输出应该是:
::::me_namespace
有什么想法吗?我唯一能想到的是将过程定义放在文件中,然后读取文件并使用 eval,但我一直在寻找更优雅的东西。 我不只使用
uplevel
的原因是,有时(特别是当
variable
与 uplevel
一起使用时,运行时间太慢了。TCL 版本是 8.6proc
。
现在,虽然我真的建议您在处理此类事情时考虑使用 TclOO,但您也许可以使用不同的技术。
namespace upvar
命令相当快,您可以像这样使用它:
proc master_version_of_foo {ns args} {
namespace upvar $ns abc local1 def local2
# ... continue with your code in here
}
# Stamp out some copies
namespace eval ::x {}
interp alias {} ::x::foo {} ::master_version_of_foo ::x
namespace eval ::y {}
interp alias {} ::y::foo {} ::master_version_of_foo ::y
namespace eval ::z {}
interp alias {} ::z::foo {} ::master_version_of_foo ::z
这些真正的命令别名非常快,变量绑定也非常快(速度与
global
命令类似;它们在内部使用几乎相同的字节码操作),并且您将共享过程本身的编译相当快。
不这样做的主要原因是如果您在三种情况下需要不同的命令分辨率。到那时,最快的路线都经过 TclOO(它驯服了 Tcl 的许多高级功能,使其变得可用),并且可能需要您进行一些认真的重新设计才能很好地使用。