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}}异常。

by
这个问题出乎意料地难以找到,可能是因为它没有提到或标记core.match,尽管那是更常见的罪魁祸首之一。

有进展吗?工单被标记为“关键”。
by
我已经标记了。它不在我们1.12的列表上,但我把它放在我们1.13的查看列表中。

10 答案

0

评论由:martinraison发表

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

0

评论由:panewman发表

我尝试使用 clojure.core.match 与 13 种模式,但在 Windows 下编译失败。我假设这是问题的根本原因。

0

_评论由: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

评论由:alexvong1995发表

你好,

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

我认为一种解决方法是提供一种选项,将类文件包裹成 jar,并使用较短的文件名,这样类名就可以保持相同(压缩文件的名称可以任意长,对吗?)。你怎么看?

顺便说一下,我正在使用 clojure 1.9.0,所以我认为我们应该说此问题影响 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 报告)
...