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.
Extensible Data Notation or EDN is the Clojure equivalent of JSON: using the language's literal syntax for data serialisation. Some people recommend EDN for serialisation in full-stack Clojure projects.
Extensible Data Notation (EDN) is a format for serializing data. EDN is a subset of the syntax used by Clojure. Reading data defined by EDN is safer than that defined by the full Clojure syntax, especially from untrusted sources. EDN is restricted to data, no code. It is similar in intent to JSON.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With