• 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