Dinesh
Dinesh

Reputation: 16436

Namespace's vairable scope in Tcl with procedures

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

Answers (1)

Peter Lewerin
Peter Lewerin

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

Related Questions