View · Search · Index
No registered users in community xowiki
in last 10 minutes

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

From: Uwe Zdun <uwe.zdun_at_wu-wien.ac.at>
Date: Wed, 19 Nov 2003 14:56:59 +0100

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_at_{xotcl,computer,acm}.org, uwe.zdun_at_wu-wien.ac.at