2017-08-16 72 views
0

这是一个简化的问题。我试图将一个过程复制到一个名称空间,以便它将使用名称空间自己的上下文。使用进口不工作(可能是因为它仅仅是创建别名)请参见下面的代码:将一个proc复制到TCL中的命名空间

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究其原因,是在时间(尤其是在使用variableuplevel是运行时,一时间,实在太慢,TCL的版本是8.6

+0

命名空间手册页(http://www.tcl.tk/man/tcl/TclCmd/namespace.htm)表示导入仅适用于导出的命令。您必须导出命令。我试过这个和':: foo :: me_namespace'工作。但是,为什么你需要在全局命名空间中导入一个过程? –

+1

看来你正在使用名称空间来实现某种类型的OOP。你考虑过TclOO吗? –

回答

1

过程必然包含其命名空间重命名过程,改变它的绑定(我讨厌这个!)要在另一个命名空间重新创建一个过程,你必须重命名(移动)或重新运行创建原始的

现在,虽然我真的建议你在使用TclOO的时候可以使用另一种技术,namespace upvar的指令相当快,而y OU也许能够使用它像这样:

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的一些高级功能以达到可用的目的),并且可能需要对您的部分进行重新设计才能使用得当。

+0

是的,我想到了TCL的OO。但有人要求采用“更简单”的方式,即通过命名空间。谢谢。 – user1134991

相关问题