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

欢迎!请参阅 关于 页面以了解更多此页面是如何工作的信息。

0 点赞
错误

我花费了几分钟的时间试图理解 Clojure 编译器给出以下消息的原因

编译异常 java.lang.RuntimeException:不允许条件读取,编译:<文件名>

最终我意识到这是因为我在一个我没有重命名为 cljc 的 .clj 文件中尝试使用读取条件。我认为对于在混用 clj 和 cljc 代码库中工作的人来说,将错误消息扩展为类似“不允许在此上下文中使用条件读取,因为文件没有 .cljc 扩展名”的内容将非常有帮助。

请求

0 点赞
评论由:alexmiller

读取器不知道这一点——它可以以多种方式调用(从 repl、通过 clojure.core/read、通过 clojure.core/read-string、加载/编译 .cljc、加载/编译 .clj),因此那个说明在某些情况下实际上是错误的。您似乎已经得到了相当好的错误消息了——它告诉了您问题所在,并给出了文件名。

消息可以被微调为类似于“在此上下文中不允许读取条件”的内容,这可能会给您更好的提示。

另一个可能在最后给出的答案档。

0 点赞

评论由:[email protected]

也许我没有理解读取器是如何确定是否允许读取条件的,但这些都似乎有不同的原因不允许,并且会被不同的检查捕捉到。每个这样的检查都可以提供一个更具体的警告来解释读取为何不被允许?

反驳我的观点,看起来只有一个地方会抛出这个异常 - https://github.com/clojure/clojure/blob/7b9c61d83304ff9d5f9feddecf23e620c0b33c6e/src/jvm/clojure/lang/LispReader.java#L1406。我不确定这能否扩展到在其它错误情况中提供更多细节,或者在那个时刻该信息并不可用吗?

0 点赞
by
_由 alexmiller 发表的评论:

读取器使用一个选项映射调用,该映射将(或将不会)具有 {:read-cond :allow} 或 {:read-cond :preserve}。这是读取器拥有的唯一信息 - 如果设置了这两个中的任何一个,并且在读取器条件遇到时,都会抛出异常。

编译器在调用读取器时决定如何初始化这些选项。read 和 read-string 的用户在调用它时也决定允许哪些选项。确实可以传递更多信息给读取器,或者在编译器中将错误捕获并重新抛出(其中已知更多上下文),但这两种方法都会使原本已经是相当好的错误处理代码变得更复杂。
0 点赞
by

评论由:[email protected]

我同意这是一个合理的错误信息,我想我们可以等一下看看1.7发布后别人怎么评价。如果这成为了很多其他人的问题,那么我们可以之后再重新讨论这个问题?

0 点赞
by

由 mars0i 发表的评论:

我在使用.clj文件中的读取器条件时遇到了问题。如果不是 Danial Compton 关于该问题的博客文章,我就不知道应该如何修复这个错误。我明白这不仅仅是文件名问题,而且还有其他可能导致此错误的原因,但是当是文件名问题时,它非常神秘,这看起来像是一个容易犯的错误。一个相关的背景是,Clojurescript 宏可以在.clj文件中定义,所以使用这个扩展名作为宏编译的提醒是很自然的。

我认为“读取器条件不允许 ...”这样的信息比“条件读取不允许”更容易理解。这至少会让问题明显,即问题是由于读取器条件引起的。一旦你了解了“条件读取”的含义,这一切都很显然,但“条件读取”在 Clojure 世界中不是一个常见的短语,据我所知,我很好奇为什么信息中没有说“读取器条件”,如果这条消息正是关于这个内容的。

(一种选择是在错误字符串中添加注释,说明问题可能是由在 .cljc 文件外部使用的读取条件引起的。不确定你是否想在错误信息中使用“可能”、“也许”这类词汇,因为这可能导致错误信息过长,难以控制。然而,这类做法在其他地方已有所应用,并且在这种情况下可能非常有用;错误地使用 .clj 与读取条件似乎是一个经常发生的问题。)

0 点赞
参考:[https://clojure.atlassian.net/browse/CLJ-1734](https://clojure.atlassian.net/browse/CLJ-1734)(由[email protected]报告)
...