For a recent problem, I was working with goog.DateTime objects and needed to send them along in JSON, specifically as #inst.
The docs for goog.DateTime say we can use them interchangeably with native js Date objects, but a quick check shows that cljs doesn’t automatically do what we want:
There are several ways to do this (e.g. convert the DateTimes to native Date objects), but really I just want DateTime objects to print like Date objects without having to think about it.
So we see the js/Date print implementation, which we’d like to use for DateTime. How to do that? Well, we see the check for implements? IPrintWithWriter, so if we implement that protocol, we can print however we want. (It’d be nice if that code was separated into it’s own function, but it’s not a big deal to just copy it.) We want to apply this for every DateTime object, so we can extend the DateTime object via extend-type:
Now, we get what we want:
Take-aways
With extend-type and IPrintWithWriter, we can simply control how various objects are printed. Even more generally, we can use extend-type and any protocol to add functionality to types/objects, without needing to break them open.
If we only cared about JSON, we could use IEncodeJS in a similar way. It’s useful to have consistent printable dates (e.g. for debugging) so IPrintWithWriter is worth using here.