(对不起,说得太长了。排除误解很长,不是因为我想让你弄清楚我的问题应该是什么。)
我了解 Clojure 命名空间的基础知识,并且我ns在文件开头的语句中列出的命名空间必须与目录层次结构中的文件位置相匹配。我已经弄清楚了 Leiningen 自动设置搜索的load部分内容,以及它自动加载的部分内容,但是......它仍然让我发疯。问题是,Leiningen 似乎隐式设置了一些东西,在Leiningen 教程和示例项目文件等明显的地方也没有很好地记录。(也许信息在那里,但我还没有找到/解释它。)
我已经设置好了,所以当我这样做时lein repl,主要的源文件被加载(下面的 popco.clj 和 acme.clj),但加载其他文件会导致麻烦。我想让 MWE 尽可能小,并且问题很简短,但我想明确表示我不是在问已经回答过的更简单的问题(例如这个)。
这是源文件所在的位置,ns右侧列出了来自相同文件的语句:
src/popco/sims/sim1/sim1propns.clj (ns popco.sims.sim1.sim1propns)
src/utils/general.clj (ns utils.general)
src/popco/core/acme.clj (ns popco.core.acme)
src/popco/core/popco.clj (ns popco.core.popco
[:use popco.core.acme]
[:import [popco.core.acme Propn Obj]]
(:gen-class)) ; not sure what this does yet
Run Code Online (Sandbox Code Playgroud)
这是 project.clj 文件:
(defproject popco-x "0.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]]
:main popco.core.popco
:profiles {:dev {:dependencies []
:source-paths ["src"] }})
Run Code Online (Sandbox Code Playgroud)
当我运行时lein repl,我看到我在popco.core.popco命名空间中:
popco.core.popco=>
Run Code Online (Sandbox Code Playgroud)
我发现 acme.clj 中定义的函数和记录类型都可用。我(通过反复试验)了解到:main popco.core.popco,project.clj中的“ ”导致 popco.clj 运行,这导致 REPL 留在popco.core.popco命名空间中。到现在为止还挺好。
以下是我的问题:
如果我想加载 src/utils/general.clj 或 src/popco/sims/sim1/sim1propns.clj 怎么办?我可以加载它们load-file,但我想用load在REPL,更重要的是,我希望能够require和use其他源文件,这些源文件。例如,如何从 acme.clj 内部引用 general.clj 中的函数?我认为答案可能是:source-paths在 project.clj之后的序列中添加条目,但我对应该去那里的内容感到困惑。
随意推荐任何东西。其他目录结构,对 project.clj 的彻底更改,等等。
关于您的项目结构和 project.clj 的一切看起来完全正常。
如果我想加载 src/utils/general.clj 怎么办:
这几乎总是通过requireoruse表达式完成的。虽然可以加载文件,load-file但这需要您指定文件的路径(相对于您启动 JVM 的位置)。load相对于类路径加载它,但实际上当加载的文件是项目的一部分时,这些几乎从不使用。在这种情况下,您可以简单地使用require它们。
我希望能够从其他源文件中要求或使用这些源文件:
这样做的预期方法是(:require [popco.core.acme :as acme])在要使用该命名空间中的函数的命名空间顶部以 ns 形式放置一个语句。
如何从 acme.clj 中引用 general.clj 中的函数:
(ns popco.core.acme
(:require [utils.general :refer [function1 function2] :as general))
我认为答案可能是在 project.clj 中的 :source-paths 之后向序列添加条目:
您很可能永远不需要在那里放置任何东西。require并且use是合适的工具。他们已经能够在 /src/ 下找到所有文件,因为当 leiningen 启动 java 时,这些文件将在类路径中。您可以看到与该lein classpath函数一起使用的类路径。
ps:您也可以调用require和use作为函数(例如形成 REPL),尽管通常首选以 ns 形式执行此操作。