Tcl/Tk: область видимости переменных для функции внутри функции

Я заблудился от определения переменных в Tcl. У меня есть два прока, которые я написал и сохранил в файле, который я хочу вызвать в другом скрипте, который я пишу. В моем исходном файле (который я назову bar.tcl), Я использую upvar определить группу переменных в начале моего файла, которые я планирую вызывать в рамках процедур, которые я определил в bar.tclкоторый я назову bar1 а также bar2

Я хочу вызвать функции внутри bar.tcl из моего кода в foo.tcl, Мои функции работают нормально, если я просто взаимодействую с bar.tcl в tclsh, но как только я вызываю bar1 или bar2 из функции в foo.tcl, я получаю ошибку can't read "alpha": no such variable

Кажется я пользуюсь upvar incorrectlys. Это даже правильный инструмент для работы? Что я могу сделать, чтобы достичь следующего?

  1. определить группу переменных в начале bar.tcl что я хочу использовать в обоих процессах bar1 а также bar2, а также
  2. вызов bar1 а также bar2 из процедур, определенных в foo.tcl

Вот мой код в foo.tcl:

# foo.tcl
source bar.tcl

proc foo {fooValues} {
    foreach fooValue $fooValues {
        set myNewValue [bar1 $fooValue]
        return $myNewValue
    }
}

set myOldValues {5 10 15 20 25}
foo myOldValues

А вот мой код в bar.tcl:

set a apples
set b bananas
set c cherries
set d dates

proc bar1 {bar} {
    upvar a alpha
    upvar b bravo
    upvar c charlie
    upvar d delta

    set myReturnValue "$bar $alpha $bravo $charlie $delta"
    return $myReturnValue
}

proc bar2 {bar} {
    upvar a alpha
    upvar b bravo
    upvar c charlie
    upvar d delta

    set myReturnValue "$alpha $bravo $charlie $delta $bar"
    return $myReturnValue
}

1 ответ

Решение

Когда bar1, bar2... вызываются изнутри foo их upvar звонки будут пытаться связать с любыми переменными proc-local выполненных foo Proc. Это потому что upvar без уровня по умолчанию upvar 1 который обозначает вызывающего процесса (т.е. foo). Ваши целевые переменные в bar.tcl однако находятся в глобальном пространстве имен, а не внутри foo, Следовательно, нет переменных, связанных alpha, bravo,

Перепишите свой upvar вхождения как upvar #0 ..., с #0 указание глобального пространства имен верхнего уровня, например:

upvar "#0" a alpha

Это эквивалентно использованию global a по модулю псевдоним переменной (alpha).

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