clojure - 如何将 *data-readers* 与 edn 一起使用?

标签 clojure edn

我尝试按照 clojure.instant/read-instant-timestamp 的文档进行操作,内容如下:

clojure.instant/read-instant-timestamp
  To read an instant as a java.sql.Timestamp, bind *data-readers* to a
map with this var as the value for the 'inst key. Timestamp preserves
fractional seconds with nanosecond precision. The timezone offset will
be used to convert into UTC.`

The following result was unexpected:


(do
  (require '[clojure.edn :as edn])
  (require '[clojure.instant :refer [read-instant-timestamp]])
  (let [instant "#inst \"1970-01-01T00:00:09.999-00:00\""
        reader-map {'inst #'read-instant-timestamp}]
    ;; This binding is not appearing to do anything.
    (binding [*data-readers* reader-map]
      ;; prints java.util.Date -- unexpected
      (->> instant edn/read-string class println)
      ;; prints java.sql.Timestamp -- as desired
      (->> instant (edn/read-string {:readers reader-map}) class println))))


如何使用 *data-readers*捆绑? Clojure 版本 1.5.1。

最佳答案

clojure.edn默认情况下,函数仅使用存储在 clojure.core/default-data-readers 中的数据读取器从 Clojure 1.5.1 开始,它为读者提供即时和 UUID 文字。如果你想使用自定义阅读器,你可以通过传入 :readers 来实现。选项;特别是,您可以传入 *data-readers* .这记录在 clojure.edn/read 的文档字符串中。 (clojure.edn/read-string 的文档字符串是指 read 的文档字符串)。

这里有些例子:

(require '[clojure.edn :as edn])

;; instant literals work out of the box:
(edn/read-string "#inst \"2013-06-08T01:00:00Z\"")
;= #inst "2013-06-08T01:00:00.000-00:00"

;; custom literals can be passed in in the opts map:
(edn/read-string {:readers {'foo identity}} "#foo :asdf")
;= :asdf

;; use current binding of *data-readers*
(edn/read-string {:readers *data-readers*} "...")

(以下部分是为了响应 Richard Möhnthis GitHub issue 的评论线程中所做的评论而添加的。直接的问题是阅读器函数是否适合对传入的数据调用 eval。我不是与有问题的项目相关联;有关详细信息,请参阅票证,以及理查德对当前答案的评论。)

值得补充的是 *data-readers*从任何 data_readers.{clj,cljc} 隐式填充Clojure 在启动时在类路径的根目录中找到的文件。这可能很方便(它允许在 Clojure 源代码和 REPL 中使用自定义标记文字),但这确实意味着新的数据读取器可能会出现在其中,并更改单个依赖项。使用带有 clojure.edn 的显式构造的阅读器映射是一种避免意外的简单方法(在处理不受信任的输入时可能会特别讨厌)。

(请注意,隐式加载过程不会导致立即加载任何代码,甚至当第一次遇到 *data-readers* 中提到的标签时;填充 *data-readers* 的过程会创建空的命名空间,并将未绑定(bind)的 Vars 作为占位符,并实际上使用这些阅读器仍然需要 require 用户代码中的相关命名空间。)

关于clojure - 如何将 *data-readers* 与 edn 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16989337/

相关文章:

clojure - Neo4J 是否适合 clojure?

parameters - 如何从另一个 ns 设置一个 ns 中的值?

clojure - 如何设置 leiningen 以处理多个项目?

emacs - Clojure 导入与 :import

clojure - 在 .edn 文件中使用 #inst 将时间戳播种到 clojure 中的 jdbc 数据库

clojure - 在 Clojure/EDN 中序列化排序的映射?

clojure - 如何将 ClojureScript 函数序列化为 edn,然后反序列化并调用它们?

clojure - 如何在不发出ajax请求的情况下将edn从clojure传递到clojurescript(即通过hiccup生成的页面)

eclipse - 如何在 Eclipse 中打开现有的 Clojure 项目?