Reputation: 16436
In Tcl, I am trying to work on namespaces and I came across the following question.
My code is as below.
% namespace eval counter {
#Declaring the variable 'num' in counter namespace
variable num 0
proc next { } {
#Accessing 'num' here, since we have already declared it in it's namespace
return [ incr num ]
}
proc reset { } {
#Same as above
return [ set num 0 ]
}
}
%########OUTPUT############
% ::counter::next
1
% ::counter::next
1
% ::counter::reset
0
% ::counter::next
1
As you can see, I am able to access the value 'num' without any issues. But, value 'num' retained it's value for each call.
By declaring the variable 'num' inside each procedures, the value retained.
% namespace eval counter {
variable num 0
proc next { } {
variable num
return [ incr num ]
}
proc reset { } {
variable num
return [ set num 0 ]
}
}
% ######OUTPUT#########
% ::counter::next
1
% ::counter::next
2
% ::counter::next
3
% ::counter::reset
0
Why this behaves in this way ?
What is the significance of declaring the variables inside procedures too ?
Upvotes: 0
Views: 200
Reputation: 13282
It's a language design choice. Tcl uses dynamic rather than lexical scope, so names aren't automatically imported everywhere even if proc
definitions are lexically parts of a namespace eval
body. It's the same thing with global names, which aren't imported into a proc
definition unless you use global
. Note that this goes both ways: if you happen to make changes to a variable with the same name as a namespace or global variable, your changes won't leak out unless you want them to (remember that Tcl uses implicit declaration of variables: set
will create a new variable only if the name isn't used already).
It can be a bother to remember to put in variable
commands in every procedure that needs them, and it's easy to get obscure bugs when you forget, but on the whole it's a sound design choice, I think.
Documentation: global, namespace, proc, set, variable
Upvotes: 4