'''[http://www.tcl.tk/man/tcl/TclCmd/global.htm%|%global]''', a [Tcl Commands%|%built-in] [Tcl] [command], declares global variables. ** See Also ** [info globals]: ** Synopsis ** : '''global''' ''varname'' ?''varname ...''? ** Documentation ** [http://www.tcl.tk/man/tcl/TclCmd/global.htm%|%official reference]: ** See Also ** [info globals]: ** Synopsys ** : '''global''' ''varname'' ?''varname ...''? ** Description ** When not in the body of a [proc]edure, `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 [proc]edure, `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. ** The Strange Ways of `global` ** `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 ====== ** Consider `[variable]` Instead ** 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. ** Performance ** 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]) ** Globbing Globals ** 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:dacut@kanga.org): ====== 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] <> Tcl syntax | Arts and crafts of Tcl-Tk programming | Command | Tcl