关闭repl中的*print-namespace-maps*

问题描述 投票:0回答:3

在 Clojure 1.9-beta2 中,读者和作者现在支持紧凑的映射语法。在所有键都是具有相同名称空间的限定关键字的情况下,语法避免重复名称空间:

> (pr-str {:a/foo 1 :a/bar 2})
"#:a{:foo 1, :bar 2}"

将这样的序列化映射发送到 Clojure 1.8 进程时会导致问题:在那里运行的旧阅读器将无法读取它并抛出

java.lang.RuntimeException: Reader tag must be a symbol

幸运的是,打印机仅在动态变量

*print-namespace-maps*
为真时才执行此操作,并且默认情况下为假,因此我的应用程序可以继续在生产环境中工作。然而,REPL 将其设置为 true,因此当我在 REPL 中工作并执行一些最终向 Clojure 1.8 服务发送请求的操作时,它会失败。 如何在 REPL 中禁用新语法?

我想也许我可以在我的 repl 中添加

(set! *print-namespace-maps* false)
或将
{:user {:repl-options {:init (set! *print-namespace-maps* false)}}}
添加到我的 ~/.lein/profiles.clj 中,但这似乎不起作用。我认为原因可能是 REPL 使用
binding
为包括这个在内的一堆变量创建线程局部绑定,而
set!
不适用于局部变量绑定

clojure
3个回答
3
投票

您可以为地图重新定义

print-method
,无论环境如何,它都应该有效。

(defmethod print-method clojure.lang.IPersistentMap [m, ^java.io.Writer w]
  (#'clojure.core/print-meta m w)
  (#'clojure.core/print-map m #'clojure.core/pr-on w))

1
投票

使用

(set! *print-namespace-maps* false)
对我有用。 (但这已经是大约 5 年后的事了。)

这也有效,有时可能更理想:

(binding [*print-namespace-maps* false] 
  (pr-str {:a/foo 1 :a/bar 2}))
=> "{:a/foo 1, :a/bar 2}"

0
投票

您还可以使用以下命令设置此设置:

(set! *print-namespace-maps* false)

并且至少会在 REPL 会话期间进行设置。

© www.soinside.com 2019 - 2024. All rights reserved.