betontalpfa
betontalpfa

Reputation: 3742

Cannot define namespace variable which was defined globally TCL

I cannot define variables in namespace (in TCL) which was defined previously in global scope. See my example:

xsct% $tcl_version
[8.5]
xsct% set foo 1
1
xsct% $foo
[1]
xsct% namespace eval ns {
set foo 2
set bar 3
}
3
xsct% $::ns::bar
[3]
xsct% $::ns::foo
can't read "::ns::foo": no such variable
xsct%

I have reproduced the issue online: http://tpcg.io/3SIBYG

How can I define variables in namespaces independently from global scope?

I use:

Upvotes: 1

Views: 407

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137557

Always define variables in a namespace with the variable command at least the first time you access them, otherwise you end up with namespace variable resolution rules taking over and making your life unpleasant. They're weird (though actually very similar to how command resolution works) and you virtually never want them, and may get removed in Tcl 9. But until then, you're stuck doing:

namespace eval ns {
    variable foo 2
    variable bar 3
}

or:

namespace eval ns {
    variable foo
    set foo 2
    variable bar
    set bar 3
}

If you want to do arrays, you can. Do them like this (with only one argument to variable):

namespace eval ns {
    variable ary
    array set ary {foo 2 bar 3}
}

What the variable command actually does is make the variable in the namespace in unset state so that it still resolves when commands like set and array can find the variable and write to it.

Upvotes: 2

Related Questions