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

欢迎!请访问关于页面以了解更多关于如何使用本社区的信息。

+6
编译器
编辑

Clojure编译器生成的类名字符长度可以是任意的,超出文件系统允许的最大文件名长度。例如,当你函数嵌套太深时就会发生这种情况

(defmacro nestfn [n & body]
  (if (> n 0)
    `(fn [] (nestfn ~(- n 1) ~@body))
    body))

(def myf (nestfn 100 "body"))

编译时产生//{{java.io.IOException: 文件名过长}}异常。

这个问题很难找到,可能是因为它没有提及或标记core.match,尽管这是更常见的错误原因之一。

是否有任何进展?工单被标为“重要”。
我对它进行了标记。它不在我们1.12的列表中,但我在1.13的列表中查看它。

10 个回答

0票数

评论由:martinraison

Scala 社区在一段时间之前发现了这个问题,现在编译器有了一个 {{max-classfile-name}} 参数(默认为255)。当超过限制时使用哈希。我们也许应该考虑类似的方法?

0票数

评论由:panewman

我在 Windows 下使用 clojure.core.match 和 13 种模式时遇到问题,编译失败。我假设这是原因所在。

0票数

_评论由:chris_betz

关于这个问题的一些信息

我的一个同事遇到了这个问题,因为他在使用 Linux / eCryptfs(与其他 FileVault 加密的 macOS 相比,其限制 143 较小):请参阅 https://bugs.launchpad.net/ecryptfs/+bug/344878.

当然,Clojure 并不是唯一遇到这个问题的,Scala 也受到了严重影响:https://issues.scala-lang.org/browse/SI-3623

没有“简单”的解决方案,显然,像 Scala 那样截断文件名会带来许多其他问题。

对于所有受到此问题困扰的人,可能的一个解决办法是 Mario Pastorelli 在评论https://issues.scala-lang.org/secure/ViewProfile.jspa?name=melrief)中提出的,请参阅评论 https://issues.scala-lang.org/browse/SI-3623?focusedCommentId=76104&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-76104

使用未加密的文件系统临时存储类文件,比如通过 tempFS 在内存中保存内容。这不是最好的方法,因为我们不喜欢留下未加密的重要数据...

0票数

评论由:alexvong1995

你好,

我在使用 clojure.core.match 时遇到了相同的问题。我展开函数定义,观察到宏展开的定义非常嵌套。

我认为解决方法之一是提供一个选项将类文件打包为 jar 文件,并使用较短的文件名,这样类名可以保持不变(压缩文件名可以很长,对吧?)。你怎么看?

顺便说一句,我正在使用 clojure 1.9.0,因此我认为这个错误也影响 1.9。

0票数

评论由:alexvong1995

我提出了一个概念性补丁。当类名长度超过255时,编译器现在输出jar文件而不是类文件。jar文件名只是类名的简单(左)截断。

假设**compile-path**设置为"build",则您需要将build/添加到您的类路径中,以便能够找到jar文件。

这个补丁只是一个概念性证明,理想情况下,所有具有长名称的类都应放入一个大jar文件中,以避免需要解压缩许多文件。此外,用户应能够指定**compile-name-max**和**compile-jar-name**。最后,代码相当糟糕,我应该将这些内容分散到几个函数中。

0票数

评论者:alexmiller

Alex - 我们不会输出jar文件。这与Clojure运行时的许多方面相矛盾。

0票数

评论者:[email protected]

如果这个评论不太相关,请见谅。原始示例对我来说有点 confusing。也许应该是:

`
(defmacro nestfn [n & body]
(if (> n 0)

`(fn [] (nestfn ~(dec n) ~@body))
`(do ~@body)))

`

这样 (trampoline (nestfn 10 "foo")) 就会返回 "foo"。然而,我得到一个 CompilerException: java.lang.StackOverflowError,当 n=1000 时在MacOS上运行。

0票数

评论者:gsnewmark

@Alex Miller 你好!使用与Scala类似的方法(如果名称太长则进行哈希处理)的补丁会被考虑吗?由于这会破坏二进制兼容性,这个备用方案默认情况下将禁用,但可以通过使用新的编译器选项来启用名称哈希处理。这种方法确实有助于我们特定的案例,但我不确定它是否足够有用/通用,以便包含在编译器中,因此我还没有开始编写补丁。

0票数
评论者:alexmiller

不会做出任何破坏性更改。计划应该是当当前策略无效时切换到第二种策略。
0票数
参考: https://clojure.atlassian.net/browse/CLJ-1852 (由 alex+import 报告)
...