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

欢迎!请查看关于页面,以了解此功能的更多信息。

0
Clojure
当宏在REPL中失败规范检查时,打印的消息中包括spec explain生成的(通常是很大的)ex-data映射

Clojure 1.9.0-RC1
user=> (let [x] 5)
CompilerException clojure.lang.ExceptionInfo: 对clojure.core/let的调用未符合规范
In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr]
谓词: any?,  输入不足
 #:clojure.spec.alpha{:problems [{:path [:args :bindings :init-expr], :reason "Insufficient input",
:pred clojure.core/any?, :val (), :via [:clojure.core.specs.alpha/bindings
:clojure.core.specs.alpha/bindings], :in [0]}], :spec
#object[clojure.spec.alpha$regex_spec_impl$reify__1188 0x3f9270ed
"clojure.spec.alpha$regex_spec_impl$reify__1188@3f9270ed"], :value ([x] 5), :args ([x] 5)},
编译:(NO_SOURCE_PATH:18:1)

据我理解,Compiler.java中的checkSpecs调用spec的macroexpand-check。对于失败,macroexpand-check抛出一个包含解释数据映射的ExceptionInfo异常。checkSpecs捕获这个异常并抛出一个新的CompilerException,并将ExceptionInfo作为原因。CompilerException构造函数调用cause的toString,对于ExceptionInfo会生成一个包含消息和数据映射的字符串。

可能,您可以添加一个新的CompilerException构造函数重载,它指定一个显式消息和原因(使用调用errorMsg的消息)。然后checkSpecs可以使用这个重载,传入ExceptionInfo.getMessage并避免打印数据映射。

我已经将其标记为主要,因为我认为数据映射转储可能会对新手产生 intimidating的效果。

2 个答案

0

评论者:alexmiller

结果消息的混乱是由多个因素引起的,我不同意提出的解决方案。CompilerExceptions 旨在作为(带有位置信息的)包装器来展开以找到异常原因,因此从某种程度上说,REPL 捕获处理程序也应该承担一部分责任——它应该做更多的工作来解包并报告。如果我们有一个可以识别它们的标记,它甚至可以为特定于规范错误做得更多。另外,我认为宏检查不应该包括解释数据字符串。

0
参考:https://clojure.atlassian.net/browse/CLJ-2272(由 glchapman 报告)
...