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.