4

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

在 python 中,我可以像下面那样做我想做的事,但我不了解命名空间和函数句柄在 tcl 中是如何工作的。

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

2 回答 2

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有效地从调用堆栈中完全省略了包装器——诚然,在你的情况下这可能不是必需的,但能够做到这一点很好。

于 2011-05-24T18:12:32.540 回答
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 的答案更接近于我通常如何包装命令,并且它还具有使用非过程命令的优势——但是这种解决方案具有绑定代码的优势又好又紧,这样以后就不会出错了。它也不会在任何错误跟踪中引入额外的堆栈帧,这有助于保持调试简单。

于 2011-05-24T19:24:21.757 回答