2015-11-21 109 views
0

为了增强tcl/tk程序的功能,我想重新实现它的一个原始(名称空间)函数。新的实现应该调用核心功能的原始实现,并添加一些漂亮的东西。将命令重命名为不同的命名空间

这被记录得相当好using tcl's rename command

为了让事物尽可能模块化,我想将我的新功能放到一个单独的命名空间中。

我也想避免将东西添加到toobe增强功能的原始名称空间。

所以我们的计划是:

  • 重命名::simple::function::enhanced::simple_function
  • 创建一个新的::simple::function调用::enhanced::simple_function

这个作品都很好,除非原来的函数使用的其他成员公司命名空间没有完全限定他们。

下面是一个例子:

namespace eval ::foospace:: { 
    proc bar {a} { puts $a } 
    proc foo {X} { bar "foospace:foo:: $X" } 
} 
## test original function 
::foospace::foo "hello world" 

## shadowing the original ::foospace::foo into a new namespace 
rename ::foospace::foo ::barspace::foo 
proc foospace::foo {x} { 
    puts "DEBUG: $x" 
    ::barspace::foo "$x" 
} 
# test enhanced function 
::foospace::foo "goodbye moon" 

这给了我:

invalid command name "bar" 
    while executing 
"bar "foospace:foo:: $X" " 

如果原始::foospace::foo使用::foospace::bar代替bar,一切工作正常。 不幸的是我不能“修复”原来的实现。

这也将工作,如果我只是改名::foospace::foo::foospace::foo_bar而不是::barspace::foo但这意味着触及的命名空间不属于(我想避免)。

有没有办法将我的原始函数重命名为新的名称空间,并允许原函数中的非限定函数名称?

回答

1

有关过程和名称空间的一件事情是,用于过程命令和变量解析目的的当前名称空间由过程所在的名称空间决定。这意味着当您将rename过程转换为另一过程时命名空间,你改变它的行为。当大多数命令位于全局命名空间中时(大多数情况下,Tcl会搜索它是否无法在当前命名空间中找到命令),大多数情况下都会避免它,但它可能会产生相当深远的影响。可以使代码免受四处移动的影响(例如,使用完全限定的命令名和namespace upvar而不是variable),但大多数人不会打扰,因为这是几乎不需要的巨大痛苦。

建议您不要在名称空间内重命名。它会导致难以调试的麻烦(我可以根据具体情况对其进行解释);你看到的问题是这样的症状,并且不,不能重命名我的原始函数到一个新的命名空间,并允许原始函数中的非限定函数名称。

还有其他技术。命令执行跟踪可能是合适的,可能使用命名空间导入。或者它可能是你试图做一个伪对象系统:如果是这样的话,你应该切换到其中一个真正的对象,因为它们处理你没有想到的许多许多问题。 (我最喜欢的是TclOO,作为Tcl 8.6的一部分发布,但后来我写了它,所以我有点偏颇!)使用真实对象系统可以使事情变得更简单。

+0

可以说,Tcl目前的行为与程序的重命名是错误的。我会是会争辩的人之一。详细说明请参考 –

+0

thx;我想知道是否有办法获得给定过程的代码(文本)表示,并将所有符号解析为该过程所使用的任何名称空间(当前)......然后可将其作为功能相同的“相同”替代。 –

+0

无论如何,我不认为我想在这里做OO(即使我更喜欢在更一般的水平)。 –