Clojure - 相对于项目读取文件

11

我有一个使用leinigen创建的项目,其中我在src/some_project_name目录中保存了clj文件(与自动生成的core.clj文件并排)。

这些clj文件还保存了我想要从它们旁边的clj文件中 slurp 的文本文件。我的理解是读取文件是相对于工作目录的,并且工作目录将是您从哪里启动REPL。我从所有文件都位于其中的src/some_project_name中启动了REPL,而不是根目录。 (System/getProperty "user.dir") 确认这是活动目录。

但是我也读过,slurp会查找相对于根目录的文件,这显然是发生的事情,尽管从src/some_project_name内部启动了REPL。为了找到它们,我必须列出相对于根目录的文本文件路径,例如“src/some_project_name/foo.txt”,而不仅仅是“foo.txt”。

设置项目之前,文件可以相对于REPL正在运行的位置访问(正如我所期望的那样)。现在设置项目后,它们似乎只能相对于根目录访问,无论REPL从哪里启动。

我对此没有问题,但我不明白它。是leningen做了一些设置来拦截REPL评估,并告诉它从根目录而不是活动目录搜索吗?

1个回答

12

我相信Leiningen REPL将项目根目录作为它们的工作目录。(如果没有trampoline,它们将使用带有预期工作目录的子进程- 在lein repl之后尝试jps -l,您应该会看到两个clojure.main进程。)

另外,您可能希望使用clojure.java.io/resource使用基于类路径的路径加载文件。这样的文件通常放在resources文件夹中- 在Leiningen中,这通常是src的兄弟节点。

例如,如果您在resources/some_project_name中放置foo.txt,那么您应该能够执行以下操作:

(require '[clojure.java.io :as io])

(slurp (io/resource "some_project_name/foo.txt"))

谢谢回复 - 这再次确认了我的猜想(REPL相对于根目录),但如果您从其他位置开始它,它并没有真正告诉我为什么会这样。感谢您提供使用资源文件夹的提示 - 我很好奇,除了约定俗成之外,还有什么优点?我试图搜寻文档,但关于资源/类路径相关路径的讨论有点稀少。再次感谢。 - Solaxun
不确定您是在询问这是如何实现还是为什么以这种方式设计。如果是前者,REPL会获得自己的JVM进程,因此Leiningen只需要在正确的目录中启动这些JVM即可。在leiningen-core子项目(leiningen.core.eval)中有一个专门用于设置这些内容的命名空间。如果是后者,我可能会推测这是为了确保您的Leiningen命令的效果始终保持一致,而不受您的shell当前工作目录的任何意外影响(只要它保持在项目内)。 - Michał Marczyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接