I am observing this weird behaviour of watching a clojure ref. It seems to behave wrong/delayed when not wrapped in a let
block:
(let []
(def ^{:flag 1} v 1))
(def ^{:flag 2} v 2)
(add-watch #'v ::listener (fn [_key _ref old-value new-value]
(println "old " old-value ", new" new-value "new-meta " _ref (select-keys (meta _ref) [:flag]))))
Some random order evaluations of 1 and 2. 1 always updates meta directly whereas 2 updates meta after the second evaluation (look for subsequent "new 2")
old 2 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new nil new-meta #'adgoji.scratch-test/v {:flag 1}
old nil , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 2 new-meta #'adgoji.scratch-test/v {:flag 1}
old 2 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 2 new-meta #'adgoji.scratch-test/v {:flag 1}
old 2 , new 2 new-meta #'adgoji.scratch-test/v {:flag 2}
old 2 , new 2 new-meta #'adgoji.scratch-test/v {:flag 2}
old 2 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 2 new-meta #'adgoji.scratch-test/v {:flag 1}
old 2 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 2 new-meta #'adgoji.scratch-test/v {:flag 1}
old 2 , new 2 new-meta #'adgoji.scratch-test/v {:flag 2}
old 2 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 1 new-meta #'adgoji.scratch-test/v {:flag 1}
old 1 , new 2 new-meta #'adgoji.scratch-test/v {:flag 1}