Search code examples
wrappertcldecoratorproc-object

tcl: wrap a proc of the same name


I want to replace the definition of "proc N" with a proc of the same name and calling conventions, but with a little extra error detection code.

In python I could do what I want like below, but I don't have any grasp of how namespaces and function handles work in tcl.

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

Solution

  • Tcl's got quite good introspection on procedures. This lets you rewrite a procedure to add in some more code:

    # 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]]
    

    OK, that's not the only way to do it – Eric's answer is closer to how I'd normally wrap a command, and it has the advantage of working with non-procedure commands as well – but this solution has the advantage of binding the code in nice and tight so that there's very little to go wrong later. It also doesn't introduce extra stack frames into any error traces, which helps keep debugging simple.