question about array traces
From
Petro Kazmirchuk@vivid.tree7955@fastmail.com to
comp.lang.tcl on Sat May 9 22:10:34 2026
From Newsgroup: comp.lang.tcl
TLDR: it seems to me that "trace add variable my_array {array ...}
cmdPrefix" has rather limited use compared to {read write unset}, so
I'll really appreciate any real world docs/examples on how and when I am supposed to use it (or Tcl_TraceVar+TCL_TRACE_ARRAY in C).
Background: I have a Tcl 8.6/C++ app that exposes a tree-like C++
structure as a Tcl array: $my_array(key/subkey/subkey)
Users can:
- read a value using a key
- write a value using a key
- delete a value with [unset]
- use [array names]/get/set with a glob-pattern/* to query a subset of
this structure
This is implemented only in C++ with Tcl_TraceVar.
Although back then (years ago) the array-like API seemed simple and convenient, now I can see its limitations and rather complex C++ code,
so I'm trying to refactor it by:
- moving as much logic as possible from C++ to Tcl
- making C++ a thin layer that returns an opaque handle to the structure
and implements a set of functions to work with it
- making a proper Tcl ensemble for full access to the functionality
- on top of this ensemble I'm reimplementing the "traced Tcl array" API
for backwards compatibility with 1000s LoC that my users have written
over years. So, I've moved from Tcl_TraceVar to "trace add variable
array_name {array read write unset}"
I'm done with the read/write/unset part, this was straightforward. In
many cases users know keys in advance, and then it's enough. But often
they need to discover keys dynamically using [array names] etc, and for
this I must use the "array" ops, which after some thinking and looking
around does seem like an afterthought with serious limitations. When
this trace is invoked:
1. I don't know which subcommand caused it (names/get/set/size?)
2. I don't know what the glob pattern was
3. so, it forces me to populate the whole array with keys *and* values,
which might be expensive, even if a user is asking smth like [array
names key/subkey*] which will eventually return only a small subset of keys.
4. Finally, I have no way to distinguish [info exists my_array(key)]
from a normal read trace.
I guess, I can work around these limitations with [dict get [info frame
-2] cmd], but this looks like an awful hack, and I'm not sure how
reliable it is.
So, before I dig deeper, I'm looking around for real-world examples of
how it was supposed to be used *properly*, and what pitfalls I might encounter.
BTW I did check the Ashok's book, and it doesn't go into much detail in
this aspect either (understandably so, it's very thick already)
thanks in advance!
Petro
--- Synchronet 3.22a-Linux NewsLink 1.2