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

欢迎!请参阅关于页面了解更多有关此功能的信息。

0 投票
错误

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

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

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

"不允许在此上下文中使用读取条件,因为文件没有扩展名.cljc"

6 个回答

0 投票

评论者:alexmiller

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

可以将消息调整为例_sq_s,例如:“Reader条件在此上下文中不允许”,这可能给您提供更好的线索。

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 文件中的读取器条件时遇到了问题。如果不是Danial Compton关于这个问题的博客文章,我根本不知道如何修复这个错误。我明白这不仅是一个文件名问题,还有其他可能引起这个错误的原因,但如果是文件名问题,那是非常神秘的,而且这似乎是一个很容易犯的错误。有一个相关背景是Clojurescript宏可以在 .clj 文件中定义,所以自然可以用这个扩展名作为当宏将被编译时的提醒。

我认为“不允许读取条件”比“不允许条件读取”更容易理解。至少这会使问题明显是读取器条件引起的。一旦你知道这是什么意思,“条件读取”这个词组就很明显了,但据我所知,“条件读取”并不是Clojure世界中的常见短语,所以我很好奇为什么信息中没有说“读取器条件”,如果信息确实是关于这个的。

一个选择是在错误字符串中添加注释,指出错误的原因可能是读者条件在`.cljc`文件外使用。不确定你是否想在错误信息中使用“可能是”、“可能”这样的词汇,因为这可能会导致信息混乱,并产生冗长的错误信息。然而,在其他地方已经这样做过,这在本例中可能非常有帮助;错误地使用`.clj`与读者条件似乎会经常发生。

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