I'm setting up macros, Set, and Say. Defined in procedures.
proc Set {key value args} {
set ::$key $value
set "::key2" "$key"
}
proc Say {key} {
puts $key
}
proc Say2 {key} {
set key3 [regsub "\%" $key "\$"]
puts $key3
eval puts $key3
}
Which allows me to execute the following:
Set "test" "this should display this test text"
Say $key2 ;#should display the key "test" which is what we just set
Say $test ;#presents the value of the key test
Output
% Set "test" "this should display this test text"
test
% Say $key2 ;#should display the key "test" which is what we just set
test
% Say $test ;#presents the value of the key test
this should display this test text
So now lets say I want to reassign the variable $ to %
Set "mouse" "squeak" ;#set key mouse with value string of "squeak"
Say $mouse ;#displays the value as set above correctly
Say2 %mouse ;#start using our own characters to represent variables - switch the % for a $ and then output
However I then get when using eval,
can't read "mouse": no such variable
Output
% Set "mouse" "squeak" ;#set key mouse with value string of "squeak"
mouse
% Say $mouse ;#displays the value as set above correctly
squeak
% Say2 %mouse ;#start using our own characters to represent variables
$mouse
can't read "mouse": no such variable
I'm finding this weird because we set it above, we can recall the value using the standard $ And I can prove that the regsub in Say2 is working as it should replacing % with $.
%mouse becomes $mouse which is a valid variable. Eval $mouse outputs with no such variable
Am I missing something?
Thanks
The issue is with the proc
:
proc Say2 {key} {
set key3 [regsub {%} $key {$}]
puts $key3
eval puts $key3 ;# here
}
$mouse
does not exist in this proc
. It was not passed as a parameter, nor was it created with set
. It exists however in the global namespace. One way to reach for it is to use uplevel
in this case:
proc Say2 {key} {
set key3 [regsub {%} $key {$}]
puts $key3
uplevel puts $key3
}
Another option I often use is upvar
to bring the variable inside (though in this case, we don't want the $
anymore):
proc Say2 {key} {
set key3 [regsub {%} $key {}]
puts $key3
upvar $key3 var
puts $var
}
PS: I also went ahead and removed some backslashes since they aren't really needed in that scenario.