(defrecord MyRecord [x y])
(require '(clojure [edn :as e]))
(e/read-string (pr-str (MyRecord. 'foo 42)))

=> RuntimeException No reader function for tag user.MyRecord
clojure.lang.EdnReader$TaggedReader.readTagged (EdnReader.java:739)


Is there some incantation that will make records round-trip successfully,
like an (add-record-to-edn MyRecord) or something that could easily be used
to implement such? The clojure.edn documentation says something about
default-readers and a :readers key, but says nothing about the arguments
received by such a function or how to associate one with a particular
record name (though {'user/MyRecord (fn [something] something)} and
{:user/MyRecord (fn [something] something)} both seem like plausible
templates), and a search for ":readers" at the linked edn.org documentation
page draws a blank.

Or is it that something other than pr-str should be used to *write* records
that are to be read in with the edn reader? If so, it's not clear what.
There's no write or write-string in clojure.edn, or indeed anything public
other than read and read-string, and the documentation for the latter two
don't refer one to any function in any namespace specifically designed for
outputting objects to edn format, thus implying that pr-str ought to
suffice.

I can work around this by serializing records as maps with an added key or
something, then converting them back later -- something like

(map #(cond
         (instance? MyRecord %) (assoc (into {} %) ::record :MyRecord)
         (instance? OtherRecord %) (assoc (into {} %) ::record :OtherRecord)
         ...
         :else %) output)

used with walk to massage output for pr-str and

(map #(if-let [rtype (::record %)]
         (condp = rtype
           :MyRecord (MyRecord. (:key1 %) (:key2 %))
           :OtherRecord (OtherRecord. (:key3 %) (:keyx %) (:keyy %))
           ...)
         %) input)

to massage the input obtained from e/read, but that seems awkward and
requires manually adding clauses in both closures for each additional
record type that needs to be supported down the line. That doesn't strike
me as being "the Clojure way", where it's *usually* possible to avoid
having to add cond clauses in half a dozen different places (or even just
two) to add things, and keep all those conds in sync, if your code is
structured idiomatically.

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to