tcl: завернуть процесс с тем же именем

Я хочу заменить определение "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 ответа

Решение

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

Хорошо, это не единственный способ сделать это - ответ Эрика ближе к тому, как я обычно обертываю команду, и у него есть преимущество работы и с командами, не относящимися к процедуре, - но это решение имеет преимущество связывания кода в хорошем и плотном, так что мало что может пойти не так позже. Он также не вводит лишние фреймы стека в трассировку ошибок, что помогает упростить отладку.

Вы можете использовать rename Команда переименовать существующий процесс:

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 эффективно исключает обертку из стека вызовов - что, разумеется, может и не понадобиться в вашем случае, но приятно иметь возможность это сделать.

Другие вопросы по тегам