Question

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?

Update

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top