2024 Clojure 状态调查! 分享您的想法。

欢迎!请参阅 关于 页面以获得更多关于此处如何工作的信息。

+2
data.json
重标记

在内部,`clojure.data.json/write` 在其遇到任何 `clojure.lang.Named` 实例时调用 `name`,这会移除命名空间

(json/write {:foo/bar :baz/bork}
            *out*
            :escape-slash false)
;; => {"bar":"bork"}

`clojure.data.json/write` 函数提供了 :key-fn:value-fn 选项来改变这种(或任何其他)行为在映射键和值上

(json/write {:foo/bar :baz/bork}
            *out*
            :escape-slash false
            :key-fn (comp str symbol)
            :value-fn (fn [k v] (if (instance? clojure.lang.Named v)
                                  (str (symbol v))
                                  v)))
;; => {"foo/bar":"baz/bork"}

但它在其他上下文中不起作用(根据文档字符串,它也不是为此而设计的)

(json/write {:foo/bar [:baz/bork]}
            *out*
            :escape-slash false
            :key-fn (comp str symbol)
            :value-fn (fn [k v] (if (instance? clojure.lang.Named v)
                                  (str (symbol v))
                                  v)))
;; => {"foo/bar":["bork"]}

改变所有上下文中此行为的唯一机制是扩展 `JSONWriter` 协议,但这将全局更改行为。如果有一个选项可以在所有上下文中保留命名空间,或覆盖给定的类型如何写入而无需全局更改,这将很有帮助。


编辑
我遇到了完全相同的问题。

我也担心覆盖默认行为,以防其他库(例如,Datomic Cloud)依赖于它。

尽管如此,我已经尝试覆盖了,基于默认实现,迄今为止没有遇到任何问题

    (defn- write-named [x out options]
      (json/-write (kw->sym->str x) out options))
    
    (extend clojure.lang.Named json/JSONWriter {:-write write-named})

我想在这里放一个例子,供不太熟悉Clojure协议的人使用。
希望这是正确的做法 :)

2 条回答

+1 投票

在 https://clojure.atlassian.net/browse/DJSON-54 中有一个注释,涉及你所提到的功能。正如Alex在他的注释中所说,你的提议是一个大的变更,需要事先进行一些设计工作。尽管如此,我认为你的提议值得探索,我们可以在这张票上继续讨论。

我绕过了这个紧急需求(结果是我错误地使用了`:value-fn`,它符合我的当前需求),因此除非我的需求改变(这不是不可能的),否则我将不可能亲自参加那个讨论。我提交这个请求是因为Alex让我这样做的。
0 投票
...