Tcl: поиск переменной на всех уровнях

Предыстория моего вопроса: я хочу написать процедуру ошибки, которая выводит дополнительное сообщение, которое помогает идентифицировать ситуацию с ошибкой. У меня есть некоторые части кода, в которых предоставляется эта дополнительная информация, а в других - нет. Моя идея была:

  • установить глобальную переменную сообщения в пустую строку
  • создайте локальную переменную сообщения перед вызовом процедур, которые могут вызвать ошибки
  • в процедуре ошибки: поиск переменной вниз по всем уровням и получение значения первой найденной

Я также мог бы установить глобальную переменную и всегда обращаться к ней, но потом мне пришлось бы ее сбросить (чтобы предотвратить раздражающие сообщения об ошибках в других частях, которые не устанавливаются).

Я написал процедуру:

      proc searchVar {varname} {
    set thisLevel [info level]
    for {set lvl 0} {$lvl <= $thisLevel} {incr lvl} {
        upvar $lvl $varname var
        if {[info exists var]} {
            return $var
        }
    }
    return ""
}

Вот тестовый код:

      set message "value at global level"

proc withoutlocal1 {} {
    puts "withoutlocal1 message = [searchVar message]"
}

proc withoutlocal2 {} {
    puts "withoutlocal2 message = [searchVar message]"
    withoutlocal1
}

proc withlocal {} {
    set message "value at withlocal level"
    puts "withlocal message = [searchVar message]"
    withoutlocal2
}

withoutlocal1
puts ""

withoutlocal2
puts ""

withlocal

который дает

      withoutlocal1 message = value at global level

withoutlocal2 message = value at global level
withoutlocal1 message = value at global level

withlocal message = value at withlocal level
withoutlocal2 message = value at withlocal level
withoutlocal1 message = value at withlocal level

Это дает желаемое поведение: значение является последним определенным (относительно порядка вызова).

У меня вопрос: есть ли более компактное или «каноническое» решение для ? Или более элегантное решение всей проблемы?

0 ответов

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