2024 Clojure 调查问卷! 中分享您的观点。

欢迎使用!有关此功能的工作方式,请参阅 关于 页面以获取更多信息。

+3
Clojure

将这个表单放在 user 命名空间顶层

(set! *default-data-reader-fn* tagged-literal)

当启动 REPL(使用 Clojure 1.11.1)时会导致以下错误

Exception in thread "main" Syntax error macroexpanding at (user.clj:9:1).
	at clojure.lang.Compiler.load(Compiler.java:7665)
	at clojure.lang.RT.loadResourceScript(RT.java:381)
	at clojure.lang.RT.loadResourceScript(RT.java:368)
	at clojure.lang.RT.maybeLoadResourceScript(RT.java:364)
	at clojure.lang.RT.doInit(RT.java:486)
	at clojure.lang.RT.init(RT.java:467)
	at clojure.main.main(main.java:38)
Caused by: java.lang.IllegalStateException: Can't change/establish root binding of: *default-data-reader-fn* with set
	at clojure.lang.Var.set(Var.java:226)
	at user$eval148.invokeStatic(user.clj:13)
	at user$eval148.invoke(user.clj:13)
	at clojure.lang.Compiler.eval(Compiler.java:7194)
	at clojure.lang.Compiler.load(Compiler.java:7653)
	... 6 more

不过,在 REPL 启动后再评估相同的表单是正常的。

进一步注意,将这个表单放在 user 顶层是可以的

(alter-var-root #'*default-data-reader-fn* (constantly tagged-literal))

为什么 `set!` 在这里不起作用?如果有很好的理由,我建议更新 https://clojure.org/reference/reader#_default_data_reader_function 以提及它。

1 个答案

+2

被选中
 
最佳答案

动态变量需要在设置之前有一个根绑定!默认情况下没有这样的绑定。对于您可能熟悉的要与此类配置变量一起使用的其他配置变量,REPL 本身就在 repl 旁边设置根绑定,这使得这成为可能(请参阅 https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L82-L99)。

我最想做的事情是让 tagged-literal 成为默认的 default-data-reader-fn,这样它就会有根绑定,并且你可以进行设置!我想我们为此创建了一个工单,但找不到它,所以我为此在这里创建了一个:https://clojure.atlassian.net/browse/CLJ-2800

by
作为临时解决方案,我们可以将 `*default-data-reader-fn*` 绑定到 `nil`。这至少能解决这个具体问题,并且不会与向后兼容性产生冲突,同时让你们有时间考虑将 `tagged-literal` 设置为默认可能引发的问题。
...