Reputation: 507
In my tcl script there is a part of the code that is repeated a lot, so I want to make a procedure out of it.
The thing is this part uses dozens of variables, which I would like to avoid passing as arguments to the procedure. Is there a way to make all variables visible to the procedure? (Practically I want the "main" to branch to the procedure like a "goto" and then return and continue in main).
Edited: It does not need to be a procedure, feel free to suggest other ways to do this. The important part is not need to declare all variables/arguments passing from main to the function/procedure.
Example:
proc dummy_proc {} {
set var1 $var2
set var2 $var3
}
set var2 2
set var3 3
dummy_proc
puts "$var1 $var2"
# should print "2 3"
Upvotes: 0
Views: 2252
Reputation: 912
Use global
proc dummy_proc {} {
global var2 var3
set var1 $var2
set var2 $var3
}
set var2 2
set var3 3
dummy_proc
puts "$var1 $var2"
If you have a lot of globals you want to pass, you can use some foreach
, but than you'll have to have a way to find them all.
e.g. all globals are called GLOBAL_<SOMEARG>
proc dummy_proc {} {
foreach glb [info globals GLOBAL_*] {
global $glb
}
...
}
Upvotes: 0
Reputation: 114014
This is possible but generally not advisable due to the fact that it can make code harder to read (there's no direct indication where the variables come from or how variable values suddenly change). However in some cases this can reduce repetitive code.
Use upvar
(https://www.tcl.tk/man/tcl8.6/TclCmd/upvar.htm):
proc dummy_proc {} {
upvar var1 v1
upvar var2 v2
upvar var3 v3
set v1 $v2
set v2 $v3
}
What upvar
does is create a variable in local scope that references another variable in the caller's scope.
Alternatively you can also try using uplevel
(https://www.tcl.tk/man/tcl8.6/TclCmd/uplevel.htm):
proc dummy_proc {} {
uplevel {
set var1 $var2
set var2 $var3
}
}
What uplevel
does is similar to upvar
but instead of creating variable references it actually executes code in the caller's scope. It's as if you temporarily go back to the caller function without returning, execute some code and come back. Because you execute code in the caller's scope all variables visible in the caller's scope is visible in the code you upleveled. Uplevel behaves almost like a macro instead of a function.
Upvotes: 3