Search code examples
variablesscopeglobal-variablestcl

How do I access a variable outside of a proc


I'm trying to wrap my head around Tcl variable scopes, but I'm stuck on what I thought would be a simple concept: how can I access a variable that I've defined outside of my proc, but that I do not explicitly pass to the proc?

I'm trying to avoid setting a bunch of global variables, and only access variables that I define within a particular namespace. What do I need to add to my code below so that the proc can access the variable a, which is obviously not in the scope of the proc?

set a apples
proc myList {b c} {
   puts [concat $a $b $c]
}

Solution

  • You can use upvar:

    set a apples
    proc myList {b c} {
        upvar a a
        puts [concat $a $b $c]
    }
    

    Or, expanding the example a bit to show the "source" variable does not have to exist in the global scope:

    proc p1 {} { set a 10; p2 }
    proc p2 {} { upvar 1 a b; puts "in p2, value is $b" }
    p1
    

    outputs

    in p2, value is 10
    

    If a was defined in a namespace, you can use variable:

    namespace eval foo {
        set a apples
        # OR
        # variable a apples
    }
    
    proc foo::myList {b c} {
        variable a
        puts [concat $a $b $c]
    }
    

    Or if a was created in the global scope, you can still access it without the global function, using :: (I'll reference this SO question for this one):

    proc myList {b c} {
        puts [concat $::a $b $c]
    }