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: File name too long}} 异常。

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

是否有任何进展?该工单被标记为“严重”。
我为它添加了标签。它不在我们1.12的列表上,但我将1.13的情况列入了我们的考虑范围。

10 答案

0
by

评论由:martinraison 提供

Scala 社区很久以前就发现了这个问题,现在编译器有了 {{max-classfile-name}} 参数(默认为 255)。超过限制时使用哈希处理。也许我们应该考虑类似的功能?

0
by

评论由:panewman 提供

我在 Windows 下尝试了 13 个 clojure.core.match 模式,编译失败。我假设这是问题的根源。

0
by

_评论由:chrisbetz 提供

更多相关信息

我的一个同事遇到了同样的问题,因为他正在使用 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
by

评论由:alexvong1995 提供

Hello,

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

我认为解决方法之一是提供一个选项,将类文件作为带有较短文件名的 jar 包封装,这样类名可以保持不变(压缩文件名可以非常长,对吗?)。您的想法是什么?

顺便提一下,我正在使用clojure 1.9.0,因此我认为我们可以假设这个bug也会影响1.9版本。

0

评论由:alexvong1995 提供

我想出了一个概念验证补丁。当类名长度超过255时,编译器现在输出jar而不是class。jar名称只是类名的(左边)截取。

假设 **compile-path* 是设置为 "build",那么您需要将 build/ 添加到您的类路径中,这样才能找到jar文件。

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

0

评论者:alexmiller

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

0

评论者:[email protected]

如果这个评论跑题了,请见谅。但原始示例让我有点困惑。也许应该是

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

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

`

这样 {{(trampoline (nestfn 10 "foo"))}} 就会返回 "foo"。然而,我在macOS上对n=1000得到 CompilerException java.lang.StackOverflowError。

0

评论者:gsnewmark

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

0
评论由:alexmiller_发表

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