[Xotcl] Problem with automatic variable unsetting upon return from an instproc?

Uwe Zdun uwe.zdun at wu-wien.ac.at
Wed Nov 19 14:56:59 CET 2003


Jim,

at first glance, the behavior seems ok to me. You're setting 2 traces to the 
local scope variable "f" which get unset in reverse order -> so
the two "f" outputs should be ok.

The rhs traces "2" and "3" are for the two inner invocations. For the outer
invocations, the callframe is deleted before the Trace is executed. The 
problem here is that Tcl does not print the error that occurs.

Consider the following plain Tcl example:

proc tracecb { name1 name2 op } {
   if {[catch {
     upvar $name1 var
     puts "tracecb \"$name1\" \"$name2\" \"$op\" \"$var\""
   } err]} { 
     puts $err
   }
}
proc x {a} {
  ::trace add variable a [list unset] ::tracecb
  if {$a == 0} {return}
  incr a -1
  x $a
}

x 4

This prints:
tracecb "a" "" "unset" "0"
tracecb "a" "" "unset" "1"
tracecb "a" "" "unset" "2"
tracecb "a" "" "unset" "3"
can't read "var": no such variable

so you cannot rely on the "upvar" in the trace to a local scope variable.

You can try to refer to an XOTcl variable (an instance variable)
with "[self] trace ..." instead.

Uwe


On Tuesday 18 November 2003 22:39, Jim Russell wrote:
> I've compiled XOTcl 1.0.2 with Tcl 8.4.4 to create a xotclsh.  When I
> execute the script below, the traced variables are unset once too few
> times.  Also, the order of the unsetting seems odd.  Am I just confused,
> or I have discovered a problem?
>
> Here's the sample output:
>
> russell> xotclsh factorial.xotcl
> rhs = 3
> rhs = 2
> rhs = 1
> tracecb "rhs" "" "unset" "2"
> tracecb "rhs" "" "unset" "3"
> tracecb "f" "" "unset" "::factorial-1"
> tracecb "f" "" "unset" "::factorial-0"
> 3! = 6
>
>  >>>>  File factorial.xotcl  <<<<
>
> proc tracecb { name1 name2 op } {
>      upvar $name1 var
>      puts "tracecb \"$name1\" \"$name2\" \"$op\" \"$var\""
> }
>
> xotcl::Class factorial;
> factorial proc new { args } {
>      eval my [ my autoname factorial- ] $args
> }
>
> factorial instproc compute { rhs } {
>      puts "rhs = $rhs"
>      if { $rhs > 1 } {
>          set f [ factorial new ]
>
>          ::trace add variable f [list unset] tracecb
>
>          set lhs [ $f compute [ expr $rhs - 1 ] ]
>      } else {
>          set lhs 1
>      }
>      set product [ expr $lhs * $rhs ]
>
>      ::trace add variable rhs [ list unset ] tracecb
>
>      return $product
> }
>
> proc main { value } {
>      set f [ factorial new ]
>      puts "${value}! = [ $f compute $value ]"
> }
>
> main [expr [ llength $argv ] ? [ lindex $argv 0 ] + 0 : 3 ]
>
> _______________________________________________
> Xotcl mailing list  -  Xotcl at alice.wu-wien.ac.at
> http://alice.wu-wien.ac.at/mailman/listinfo/xotcl

-- 
Uwe Zdun
Department of Information Systems, Vienna University of Economics
Phone: +43 1 313 36 4796, Fax: +43 1 313 36 746
zdun@{xotcl,computer,acm}.org, uwe.zdun at wu-wien.ac.at





More information about the Xotcl mailing list