BUG: array traces and setting elements via upvar 
Author Message
 BUG: array traces and setting elements via upvar

With a trace on an array, setting an individual element is supposed to
invoke the trace procedure.  This apparently doesn't happen when
an array element is upvar'd into another variable and then set.

An example:

        proc Trace args {puts "** Trace $args"}
        trace variable x w Trace
        trace variable x(y) w Trace

        # here you will see two identical calls to Trace, one for the array,
        # and one for the element
        set x(y) 1
        puts "x(y)=$x(y)\n"

        # again, two calls to Trace
        upvar 0 x y
        set y(y) 2
        puts "x(y)=$x(y)\n"

        # Here, only the second trace gets invoked
        upvar 0 x(y) z
        set z 3
        puts "x(y)=$x(y)\n"

        # Again, only the second trace gets invoked
        proc PrefValueSet {_var _value} {
                upvar #0 $_var var
                set var $_value
        }
        PrefValueSet x(y) 4
        puts "x(y)=$x(y)\n"

The output, for 7.5, 7.6p2, and 8.0a2, is:

        ** Trace x y w
        ** Trace x y w
        x(y)=1

        ** Trace y y w
        ** Trace y y w
        x(y)=2

        ** Trace z {} w
        x(y)=3

        ** Trace var {} w
        x(y)=4

The PrefValueSet example is from the Exmh Preferences code, which
I am (re)using in another application.  I just merely wanted to
trace a preferences value to catch when it changes.

At the very least, I'd like to see a modification to the trace(n) and
the Tcl_TraceVar(3) man pages to reflect this behavior.  Ideally,
I'd love to see array traces inherited by upvar'd array elements.

John

(p.s., I could swear I stumbed across this back a few months ago,
       but I can find no record of me reporting this)



Fri, 05 Nov 1999 03:00:00 GMT  
 BUG: array traces and setting elements via upvar

I should point out that the workaround for this is code I wrote over a year
ago for obTcl (the set method in the Base class).  It means that if you want
to allow array traces to work when setting elements, you cannot write
code like this:

        proc Set {_var _value} {
                upvar #0 $_var var
                set var $_value
        }

Instead, use this

        proc Set args {
                set var [lindex $args 0]
                regexp -- {^([^(]*)\(.*\)$} $var m var
                global $var
                return [eval set $args]
        }

The trick is that "var" is either the name of the scalar or the name of
the array.

John



Sat, 06 Nov 1999 03:00:00 GMT  
 BUG: array traces and setting elements via upvar

I posted a report about a similar looking bug with the env() array last
week, but the second proc below fixes that problem with environment
propogation (presumably the trace API is responsible for syncing the
env() array).

Okay, now I'm convinced this is a bug.  If no one elses fixes it soon
(read - before I have half a day to spare) then I'll do it myself and
post the patch.

Any takers?

Quote:

> I should point out that the workaround for this is code I wrote over a year
> ago for obTcl (the set method in the Base class).  It means that if you want
> to allow array traces to work when setting elements, you cannot write
> code like this:

>         proc Set {_var _value} {
>                 upvar #0 $_var var
>                 set var $_value
>         }

> Instead, use this

>         proc Set args {
>                 set var [lindex $args 0]
>                 regexp -- {^([^(]*)\(.*\)$} $var m var
>                 global $var
>                 return [eval set $args]
>         }

> The trick is that "var" is either the name of the scalar or the name of
> the array.

> John

                Cheers,
                        Gary V Vaughan


Sat, 06 Nov 1999 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Cannot set env array element via upvar #0

2. array trace doesn't fire when an element is aliased with upvar

3. creation of array elements and write traces on an array

4. Do array element traces affect the whole array?

5. overhead of tracing arrays vs. array elements

6. Adjustable array dimensions specified via array element?

7. Problems with upvar and array tracing

8. Upvar'ed array elements and textvariable

9. Adding array elements with upvar

10. Unsetting array with element traces causes Tcl to abort

11. Shifting array element & regex on array element

12. setting property of each element in an array

 

 
Powered by phpBB® Forum Software