2012-12-26 174 views
1

我有几个函数在我导出的命名空间“b”中定义。然后我进口这些功能来命名空间:: X :: Y,正是如此:tcl命名空间错误

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中。我究竟做错了什么?

+2

将过程名称从一个名称空间导入到另一个名称空间不会更改定义该过程的名称空间,因此在调用该过程时不会更改当前名称空间。也许你可以分享更多的问题,并且会出现其他一些想法。 –

+0

如果你正在尝试做一个穷人的面向对象,**停下来!**使用其中一个_real_面向对象系统(或8.6.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包含onetwo,如果您有提供的扩展名),并且有许多可用作扩展包的旧版本。

+0

其实@Donal,我试图与几个名称空间共享代码,并且默认情况下,它们具有相同的例程访问权限,这些变量在不同的名称空间中。在我正在研究的情况下,我实现了页面,每个页面都有一个窗口和一个可以使用的大量函数。最后,我只是将这些功能包含在每个名称空间中。该应用程序用于具有命名行和列的tcl/tk电子表格程序。它的早期版本在sourceforge上是tk#。 –

+0

@Tom真的,这听起来(首先猜测),就像你重新发明了面向对象。我忘记了已经完成的时间(我已经完成了3-4次!)请不要再做。有一些非常好的生产系统(Itcl,XOTcl,TclOO)处理困难的边缘案例。节省自己很多工作! –

+0

呵呵,TclOO是封面下的命名空间。再加上一些聪明的调度代码... –