I need help with variable scope in 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"
When I execute this I get can't read "x": no such variable
The source
command is almost exactly just the same as this procedure:
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
}
(There are nuances with argument parsing, how the channel is configured, and how things are set up for things like info script
and info frame
, which make the real thing more complicated. They don't change the overall impression from the above. The real code is implemented in C.)
In particular, the script is run in the stack frame of the caller, and not in the stack frame of source
itself or the global scope. If you want to source in some other scope, you need to use uplevel
with the call to source
:
proc test {} {
# Run the script globally
uplevel "#0" [list source b.tcl]
}
In the case where the filename is free of Tcl metacharacters (commonly true of your own code), you can be sloppy:
proc test {} {
# Run the script in the caller's scope
uplevel 1 source b.tcl
}