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

欢迎!请查看 关于页面 了解更多关于如何使用本网站的信息。

0
错误

我花了几分钟的时间试图理解 Clojure 编译器显示的以下消息

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

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

"不允许在文件扩展名为 .cljc 的文件中进行条件读取"

6 答案

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
评论者:alexmiller

读取器是用一个包含{:read-cond :allow}或{:read-cond :preserve}的选项映射调用的。这是读取器所拥有的唯一信息 - 如果设置了这两个选项之一并且遇到读取器条件,它就会抛出。

编译器决定调用读取器时如何初始化这些选项。使用read和read-string的用户在调用时会决定允许哪些选项。在读取器中传递更多信息或将异常捕获并重新抛出(在已知更多上下文的情况下)是可能的,但这两种方法都会使代码更加复杂,而这个错误在我看来已经是相当清晰的。
0

评论者:[email protected]

我同意这应该是一个合理的错误信息,我认为我们可以先看看1.7发布后其他人是如何看待的。如果这会成为很多其他人的问题,那么我们可以在那时再回顾这个问题?

0

评论者:mars0i

我在使用.clj文件中的读取器条件时遇到了问题。如果不是因为Daniel Compton的博客文章,我对如何修复这个错误一无所知。我理解这不仅仅是一个文件名问题,还存在其他可能引发此错误的原因,但当这是文件名问题时,它非常神秘,这看起来像是一个很容易犯的错误。一个相关的上下文是,Clojurescript宏可以在.clj文件中定义,因此使用这个扩展名作为宏编译时间的提醒似乎是自然的。

我认为“读取器条件不允许...”比“条件读取不允许”更容易理解。这至少会显而易见地表明是读取器条件导致的问题。一旦你知道“条件读取”指的是什么,那就很明显了,但“条件读取”并不是在Clojure领域中常见的短语,从我了解的情况来看,我纳闷为什么不直接说“读取器条件”如果这条信息是关于这个的。

(可以添加一条注释到错误字符串中,说明原因可能是使用了在 .cljc 文件之外的条件读取器。不确定是否希望在错误消息中使用“可能是”/“也许”这样的表达,因为这可能会导致错误消息过长。然而,这种情况在其他地方已经出现过,并且在这种情况下可能非常有用;错误使用 .clj 与条件读取器的情况看起来可能会经常发生。)

0
...