global , a built-in Tcl command, declares global variables.
When not in the body of a procedure, global declares a variable named varname in the current namespace, unless a variable by the same name exists in the global namespace, in which case it refers to that variable. This is likely a bug, albeit a long-standing one. Consider using variable instead.
Inside the body of a procedure, global declares a variable named varname in the global namespace,not in the current namespace, and makes it visible by the same name in the body of the procedure. varname refers to the global variable for the duration of the procedure, even if it is unset and subsequently set.
global isn't always global. In the following example, global declares var1 to be a variable in ns1:
namespace eval ns1 { global var1 set var1 hello } puts $var1
Because var1 is in ns1, the result is an error:
can't read "var1": no such variable
Using variable in place of global is often good practice, even when the variable is global. If you later decide that you want to encapsulate a group of globals in a namespace, you can do so easily. If you have something like:
proc myProc {} { global myvar1 global myvar2 # ... }
you have to go off and edit a bunch of code if you later decide that myProc and its associated variables should be in a namespace. If instead you say:
proc myProc {} { variable myvar1 variable myvar2 # ... }
the variables are still global, but the procedure becomes easy to encapsulate: just wrap it in namespace eval:
namespace eval myNamespace { proc myProc {} { variable myvar1 variable myvar2 # ... } }
and now myvar1 and myvar2 are namespace variables. In general, you should use [global] only when you have a particular reason to make a variable global -- such as making it the text variable of a widget. Even then, consider something like:
label .path.to.label -textvariable [namespace current]::varName
LV 2003-07-07: In the above discussion, we see variable recommended over global. Is variable better to use than the ::name notation as well?
DGP 2003-07-07: For the purpose we are discussing, yes. If you want to keep a body of code free to move from one namespace to another, you should use relative variable names, and make use of variable and namespace which -variable to set up scope and generate fully qualified names as needed.
In recent versions of Tcl, using global performs significantly better than accessing global variables by their fully-qualified names, even if they are only used once in a proc. This is the opposite of the historical situation (as described in the paragraph below), and is likely due to Tcl 8.5 adding bytecode compilation for global.
In older versions of Tcl, globals are expensive if you call them only a few times in the proc - the cost of the initial linking to a local variable weighs heavily; they are quite fast if you use them a lot (the breakeven seems to be around 15 reads ...). For fewer calls, use fully qualified variable names (::name) instead. (from: Can you run this benchmark 10 times faster)
Want to import several globals in one go, with glob wildcards (similar to the public statement in VB)? The following example is by David Cuthbert (mailto:[email protected] ):
proc globalpat {args} { foreach pattern $args { set varnames [info globals $pattern] if {[llength $varnames] != 0} { uplevel 1 global $varnames } } } proc foo {} { globalpat *tcl* puts $tcl_patchLevel } foo
Result:
8.2.2
MG You can also use
global {*}[info globals $pattern]