I would like to write out an EDN data file from Clojure as tagged literals. Although the clojure.edn API contains read
and read-string
, there are no writers. I'm familiar with the issue reported here. Based on that, it's my understanding that the pr
and pr-str
functions are what are meant to be used today.
I wanted to check with the StackOverflow community to see if something like the following would be considered the "correct" way to write out an EDN file:
(spit "friends.edn" (apply str
(interpose "\n\n"
[(pr-str (symbol "#address-book/person") {:name "Janet Wood"})
(pr-str (symbol "#address-book/person") {:name "Jack Tripper"})
(pr-str (symbol "#address-book/person") {:name "Chrissy Snow"})])))
If you are using EDN in production, how do you write out an EDN file? Similar to the above? Are there any issues I need to look out for?
The Clojure Cookbook entry, "Emitting Records as EDN Values" contains a more thorough explanation of this issue and ways to handle it that result in valid EDN tags.
you should not need to generate the tags manually. If you use any of the clojure type definition mechanisms they will be created by the printer. defrecord is particularly convenient for this.
(ns address-book)
(defrecord person [name])
(def people [(person. "Janet Wood")
(person. "Jack Tripper")
(person. "Chrissy Snow")])
address-book> (pr-str people)
"[#address_book.person{:name \"Janet Wood\"}
#address_book.person{:name \"Jack Tripper\"}
#address_book.person{:name \"Chrissy Snow\"}]"
if you want them formatted more nicely you can combine with-out-str
and clojure.pprint/pprint
. Using Clojure types to create the tags also gives you reading of those tags for free.
address-book> (read-string (pr-str people))
[#address_book.person{:name "Janet Wood"}
#address_book.person{:name "Jack Tripper"}
#address_book.person{:name "Chrissy Snow"}]
address-book> (def read-people (read-string (pr-str people)))
#'address-book/read-people
address-book> (type (first read-people))
address_book.person
The only downside I see is that you lose some control over the way the tags look if you have -'s in your namespace because java classes can't contain these so they get converted to underscores.