Skip to content

Latest commit

 

History

History
88 lines (69 loc) · 3.06 KB

File metadata and controls

88 lines (69 loc) · 3.06 KB

coll-tracker

Track which keys and indices of a deep data structures are accessed.

main / Deploy Clojars Project

Usage

; require the namespace
(require '[eu.esuomi.code.coll-tracker :as tracker])

; define some data
(def data {:simple 1 
           :nested {:value 2 
                    :deeply {:final-value 3}}
           :another 4
           :sequences [#{:awesome :cool}
                       #{:hot :lit}
                       [6 7]]})

; you need an atom for tracking
(def tracker (atom #{}))
(def tracked (tracker/tracked data tracker))

; use the tracked data structure
(println (get tracked :simple)
         (some-> tracked :nested :value)
         (get-in tracked [:nested :deeply :final-value])
         ((juxt first second) (-> tracked :sequences (nth 2))))
; => 1 2 3 [6 7]

; see which paths were accessed
(println (sort @tracker))
; => ([:nested] [:sequences] [:simple] [:nested :deeply] [:nested :value] [:sequences 2] [:nested :deeply :final-value])

; Note! Accessing the original data does not impact the tracker
(println (get data :another)
         (-> data :sequences (nth 1) second)
         (get-in data [:nested :value]))
; => 4 :lit 2

; reprint to see that nothing changed
(println (sort @tracker))
; => ([:nested] [:sequences] [:simple] [:nested :deeply] [:nested :value] [:sequences 2] [:nested :deeply :final-value])

The wrapper supports Clojure's ILookup, Indexed and Seqable interfaces meaning maps, vectors, lists, sets are all supported.

In case of sets a special key is used to indicate access:

(def colored (atom #{}))
(def paints (tracker/tracked {:colors #{{:name :red :value "#bb515d"}
                                        {:name :green :value "#00ff80"}
                                        {:name :blue :value "#0c5daa"}}}
                             colored))
(println (-> paints :colors first :value)) 
; => "#<hex value>"
@colored
; => #{[:colors] [:colors :*]}

The tracked data structure decorates printing with a #tracked:

(println paints)
; => #tracked {:colors #{{:name :blue, :value #0c5daa} {:name :green, :value #00ff80} {:name :red, :value #bb515d}}}

The paths are useful, but a trie-like map is more readable to see what was used. Utility function is provided for this purpose:

(clojure.pprint/pprint (tracker/paths->map @tracker))
; => {:sequences {2 nil},
;     :nested {:value nil, :deeply {:final-value nil}},
;     :simple nil}

GenAI Usage Disclosure

OpenAI's ChatGPT with GPT-4.1 model was used to create parts of this library. As such the license is chosen as a very permissive one as I cannot claim ownership of a product of an amalgamation of all those who became before me.

License

All assets and code are under the CC0 LICENSE and in the public domain unless specified otherwise.