I'm wondering if anyone can explain the behind-the-scene details of why I can chain upvars successfully in nested procs, but it does not work in nested TclOO methods (those methods overridden in child classes). (I've been told that calling [next] in a TclOO class method acts a bit like a "temporary tailcall", in that a new stack level is not created. Is it this the case? If so, what is the complete picture?)
For example, the following three approaches do not all give the same result:
proc addone {varname} {
upvar $varname x;
incr x;
}
proc addanotherone {varname} {
upvar $varname xx;
addone xx;
incr xx;
}
oo::class create C1 {
method addone {varname} {
upvar $varname x;
incr x;
}
}
oo::class create S1 {
superclass C1;
method addone {varname} {
upvar $varname xx;
next xx;
incr xx;
}
}
oo::class create S2 {
superclass C1;
method addone {varname} {
upvar $varname xx;
next $varname;
incr xx;
}
}
set s1 [S1 new];
set s2 [S2 new];
set y 1;
addanotherone y;
set y; # First result gives 3, as expected;
set y 1;
$s1 addone y;
set y; # gives 2, unexpected;
set y 1;
$s2 addone y;
set y; #gives 3, unexpected, because original varname seems to be "two levels" deep.
If [next] somehow runs in the same stack level, can it create variables in the callers scope without "uplevel"?
If not, it's not really running at the same level, so is it more like a closure?
I'm interested in the real details on how it differs from, say, a tailcall, the use of uplevel, or whatever other concepts should be considered. Thank you!