2013年8月,Clojure中编写EDN文件的“正确”方式是什么?

20

我想以标记文字的形式从Clojure中编写一个EDN数据文件。尽管clojure.edn API包含readread-string函数,但没有编写器。我了解到有关此问题的报告在这里。基于这一点,我理解今天应该使用prpr-str函数。

我想向StackOverflow社区确认是否以下内容被认为是编写EDN文件的“正确”方法:

(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"})])))

如果您正在生产中使用EDN,您如何编写一个EDN文件?类似以上的方法吗?是否有我需要注意的任何问题?

更新

Clojure Cookbook条目,"将记录作为EDN值发出"包含了这个问题更详细的解释和处理它的方法,可以得到有效的EDN标签。


请查看 https://github.com/xsc/rewrite-clj。 - devth
1个回答

13

您不需要手动生成标签。如果使用任何Clojure类型定义机制,它们将由打印机创建。defrecord在这方面特别方便。

(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\"}]"

如果您希望它们的格式更好,可以结合使用with-out-strclojure.pprint/pprint。使用Clojure类型创建标签还可以免费阅读这些标签。

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

我唯一看到的缺点是,如果您的命名空间中有 -,则会丧失对标签外观的某些控制,因为Java类不能包含这些内容,所以它们会转换为下划线。


1
仅使用 pr-str 可能不足以满足需求,如果 print-length 绑定到某个值 - Rulle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接