Using Clojure 1.8.0
I'm trying to get a defrecord
with custom formatting in an otherwise default-formatted nested structure, for use with EDN, so I need a tagged representation. I could get away with the default one if it would come through in pprint
, but I'd prefer a custom one. As it is, I can't get pprint
to show the custom one without resorting to setting *print-pprint-dispatch*
to pr
, which destroys the nice line breaks, etc., that pprint
provides.
user> (defrecord junkrecord [val])
user> (def junk1 (->junkrecord 10))
user> (def junk2 (->junkrecord 20))
user> (pprint {:key1 junk1, :key2 junk2, :key3 (java.time.LocalTime/now)})
{:key1 {:val 10},
:key2 {:val 20},
:key3 #object[java.time.LocalTime 0xbf97341 "15:04:43.487"]}
The defrecord
shows up without the hashtag like the LocalTime
object does, but the hashtag for the defrecord
is what I want. This issue is mentioned as unresolved in https://dev.clojure.org/jira/browse/CLJ-1890 .
I created a print-method
for my defrecord
which works properly when used with (pr ...)
.
user> (defmethod print-method junkrecord [obj writer] (.write writer (str "#ThisIsWhatIwant" (.val obj))))
user> (pr junk1)
#ThisIsWhatIwant10
However when I run it through pprint
, I lose the indentation, line breaks, etc.
user> (with-pprint-dispatch pr
(pprint {:key1 junk1, :key2 junk2, :key3 (java.time.LocalTime/now)}))
{:key1 #ThisIsWhatIwant10, :key2 #ThisIsWhatIwant20, :key3 #object[java.time.LocalTime 0xa908e55 "15:10:09.634"]}
I was able to get it to work for a deftype
as it behaves much more like a Java class in this regard, but deftype
s are recommended for "low level" stuff, not domain stuff like a defrecord
.
user> (deftype junktype [val])
user> (def junk3 (junktype. 30))
user> (pprint {:key1 junk3, :key2 (java.time.LocalTime/now)})
{:key1 #object[user.junktype 0x54c21b73 "user.junktype@54c21b73"],
:key2 #object[java.time.LocalTime 0x20545fc3 "15:17:40.580"]}
user> (defmethod print-method junktype [obj writer] (.write writer (str "#ThisIsWhatIwant" (.val obj))))
user> (pprint {:key1 junk3, :key2 (java.time.LocalTime/now)})
{:key1 #ThisIsWhatIwant30,
:key2 #object[java.time.LocalTime 0x499bdba8 "15:18:33.230"]}
I also played around with *print-dup*
and (print-dup ...)
, etc. but this didn't yield anything.
So how do I get custom tagged printing for a defrecord
while using pprint
for the nice formatting? I've searched high and low, but have not found anything specific to this problem.
thanks!