tcl:包装一个同名的proc

buk*_*zor 4 tcl decorator wrapper proc-object

我想用一个具有相同名称和调用约定的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)
Run Code Online (Sandbox Code Playgroud)

Eri*_*ski 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]
}
Run Code Online (Sandbox Code Playgroud)

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


Don*_*ows 5

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

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

好的,这不是唯一的方法 \xe2\x80\x93 Eric\ 的答案更接近我通常包装命令的方式,并且它具有使用非过程命令的优点好吧 \xe2\x80\x93 但这个解决方案的优点是可以很好且紧密地绑定代码,这样以后就很少会出错。它还不会在任何错误跟踪中引入额外的堆栈帧,这有助于保持调试简单。

\n