Updated 2018-10-10 08:04:04 by stevel

global, a built-in Tcl command, declares global variables.

See Also  edit

info globals

Synopsis  edit

global varname ?varname ...?

Documentation  edit

official reference:

See Also  edit

info globals

Synopsis  edit

global varname ?varname ...?

Description  edit

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.

The Strange Ways of global  edit

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  edit

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  edit

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  edit

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]