Is there any way to retain the information in a ref's path?
WhittlesJr opened this issue · comments
My use case has me trying to get at the path of my #ref
without re-writing it somewhere else in the given context. For example:
;; Config
{:primitive-thing {:some :shared
:values true}
:other-thing #build-thing {:referenced-thing #ref [:primitive-thing]}}
;; An ideal reader
(defmethod aero/reader 'build-thing [_ _ thing]
(->> thing
:referenced-thing
(meta)
:ref-path
(assoc thing :knows-about)))
;; End result
{:primitive-thing {:some :shared
:values true}
:other-thing {:referenced-thing {:some :shared
:values true}
:knows-about [:primitive-thing]}}
Is this possible today, perhaps through a different approach? If not, is this easy enough to add?
This is a pretty funky use case. I don't think there's a way to annotate the value reliably, as there's many data types (numbers) which don't take metadata. There's also cases like #ref #ref [:path-to-ks]
to think about. One suggestion is to look at the macro system in aero, and see if that satisfies your needs. At the least, it would let you build a custom #ref
(e.g. #refwithmeta
) and use that instead.
I tried to make my own reader, but couldn't figure out how to actually make it work.
If the data type is not a clojure.lang.IObj
or whatever, you can just not use with-meta
. I actually found a spot in the code that I could reasonably inject just such a conditional with-meta
, but the metadata gets lost on its way through Aero's expansion logic, and that logic is a real bear to try to grok.
But anyway, I decided to go with Integrant instead of Aero. My config is not a stateful system, but Integrant handles my use case beautifully, without needing to shovel metadata around.