I am new comming of tcl. How to use tcl to imitate "set" command?
I try to build like below cold, but below code with error: unknown command name:
proc my_set {varName {value ""}} {
uplevel 0 [set $varName $value]
}
my_set a "123"
my_set b(a) "good"
puts $a; #expected: 123
puts $b(a); #expected: good
In your my_set proc, the script set $varname $value is called, and then its result is passed as an argument to the uplevel command, which will try to run that result as a script.
To have it do what you want:
proc my_set {varname {value ""}} {
uplevel 1 [list set $varname $value]
}
or
proc my_set {varname {value ""}} {
upvar 1 $varname target
set target $value
}
or
proc my_set {varname {value ""}} {
tailcall set $varname $value
}
The first (using uplevel) constructs the command to run in the caller's frame (the 1 argument) as a list, and then uplevel runs that list as a command 1 frame up the stack.
The second aliases the local variable target in the my_set proc to the variable whose name is in the varname variable, 1 level up the stack. So setting the target variable within the my_set proc also sets the variable called $varname in the caller's frame.
The third (using tailcall) replaces the callframe of the my_set with the command set, which is then executing as if it was called from the parent frame.
Of the three, I would probably pick the second (using upvar) because there is less potential for nasty surprises waiting in your future (uplevel is essentially eval - incautious use can open remote code execution vulnerabilities), and, unless you like obscure constructions for their own sake, the tailcall implementation is probably just too weird.