这是一个问题的简化案例。我正在尝试将过程复制到命名空间,以便它将使用命名空间自己的上下文。使用导入不起作用(可能是因为它只是创建别名)请参阅下面的代码:
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第1行输出应为:
::::me_namespace
有什么想法吗?我唯一能想到的是将程序定义放在一个文件中,然后读取文件,并使用eval,但我正在寻找更优雅的东西。
我不仅仅使用uplevel
的原因是,有时(特别是当variable
与uplevel
一起使用时,运行时间太慢了.TCL版本是8.6
答案 0 :(得分:1)
程序绑定到其包含的命名空间。重命名该过程,更改其绑定。 (我讨厌这个!)要在另一个命名空间中重新创建一个过程,您实际上必须重命名(移动)或重新运行创建原始命名空间的proc
。
现在,虽然我真的建议您在进行此类操作时使用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的一些高级功能驯服到可用的位置)并且可能需要进行一些严格的重新设计才能使用。