tcl:包装一个同名的proc

时间:2011-05-24 17:57:59

标签: wrapper tcl decorator proc-object

我想将“proc N”的定义替换为具有相同名称和调用约定的proc,但需要一些额外的错误检测代码。

在python中,我可以按照下面的方式执行我想要的操作,但是我没有掌握命名空间和函数句柄在tcl中的工作方式。

__orig_N = N
def N(arg1, arg2):
    if arg1 != 'GOOD VALUE':
        exit('arg1 is bad')
    return __orig_N(arg1, arg2)

2 个答案:

答案 0 :(得分:10)

您可以使用rename命令重命名现有的proc:

rename N __orig_N
proc N {arg1 arg2} {
    if { $arg1 != "GOOD_VALUE" } {
        puts stderr "arg1 is bad"
        exit 1
    }
    return [uplevel 1 __orig_N $arg1 $arg2]
}

这实际上比python原版稍微复杂一点,因为uplevel的使用完全有效地从调用堆栈中删除了包装器 - 在你的情况下可能没有必要,但是它是很高兴能够做到。

答案 1 :(得分:4)

Tcl对程序有很好的反省。这使您可以重写一个过程以添加更多代码:

# Assume there are no defaults; defaults make this more complicated...
proc N [info args N] [concat {
    # Use 'ne' for string comparison, '!=' for numeric comparison
    if {$arg1 ne "GOOD VALUE"} {
        error "arg1 is bad"
        # The semicolon is _important_ because of the odd semantics of [concat]
    };
} [info body N]]

好吧,这不是唯一的方法 - Eric的答案更接近于我通常如何包装命令,并且它具有使用非程序命令的优势 - 但这种解决方案具有以下优点:将代码绑定在良好和紧密的状态,以便以后几乎不会出错。它也不会在任何错误跟踪中引入额外的堆栈帧,这有助于简化调试。