Мне нужна помощь с областью видимости переменных в tcl

% cat b.tcl

set x 1
set y 2
set z 3

% cat a.tcl

proc test {} {
  source b.tcl
}
test
puts "x : $x, y: $y, z: $z\n"

Когда я выполняю это, я не могу прочитать "x": такой переменной нет

1
Rancho 1 Сен 2020 в 09:13

2 ответа

Лучший ответ

Команда source почти такая же, как эта процедура:

proc source {filename} {
    # Read in the contents of the file
    set f [open $filename]
    set script [read $f]
    close $f

    # Evaluate the script in the caller's scope
    uplevel 1 $script
}

(Есть нюансы, связанные с синтаксическим анализом аргументов, настройкой канала и настройками таких вещей, как info script и info frame, которые усложняют реальную ситуацию. Они не меняют общего впечатление от вышесказанного. Реальный код реализован на C.)

В частности, сценарий запускается в стековом фрейме вызывающей стороны, а не в стековом фрейме самого source или глобальной области видимости. Если вы хотите использовать источник в какой-то другой области, вам нужно использовать uplevel с вызовом source:

proc test {} {
    # Run the script globally
    uplevel "#0" [list source b.tcl]
}

В случае, когда filename не содержит метасимволов Tcl (обычно это верно для вашего собственного кода), вы можете быть небрежным:

proc test {} {
    # Run the script in the caller's scope
    uplevel 1 source b.tcl
}
4
Donal Fellows 1 Сен 2020 в 09:07

Хорошо, похоже, return [uplevel 1 source $file] работает! Спасибо

-1
Rancho 1 Сен 2020 в 06:28