(对不起,这太长了。排除误解的时间很长,不是因为我想让你弄明白我的问题应该是什么。)
我理解Clojure名称空间的基础知识,并且文件开头的ns
语句中列出的名称空间必须与目录层次结构中文件的位置匹配。我已经弄清楚了Leiningen自动设置搜索load
的部分内容,以及它自动加载的部分内容,但......它仍然让我发疯。问题在于Leiningen似乎隐含地设置了一些东西,在Leiningen tutorial和sample project file等显而易见的地方也没有很好地记录。 (也许信息在那里,但我没有找到/解释它。)
我已经设置好了,所以当我lein repl
时,主要的源文件被加载(下面的popco.clj和acme.clj),但加载其他文件会造成麻烦。我想尽可能少地使用MWE,问题很简短,但我想明确表示我并不是要求已经回答的更简单的问题(例如this one)。
这是源文件的位置,右侧列出了相同文件中的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
这是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"] }})
当我运行lein repl
时,我发现我在popco.core.popco
命名空间中:
popco.core.popco=>
我发现acme.clj中定义的函数和记录类型都可用。我已经(通过反复试验)了解到project.clj中的“:main popco.core.popco
”导致popco.clj运行,这导致REPL被保留在popco.core.popco
命名空间中。到目前为止,非常好。
以下是我的问题:
如果我想加载src / utils / general.clj或src / popco / sims / sim1 / sim1propns.clj怎么办?我可以使用load-file
加载它们,但我想在REPL中使用load
,更重要的是,我希望能够require
或use
来自其他源文件的这些源文件。例如,如何从acme.clj中引用general.clj中的函数?我认为答案可能是在project.clj中:source-paths
之后向序列添加条目,但我对应该去哪里感到困惑。
随意推荐任何东西。其他目录结构,对project.clj的根本性改变,无论如何。
答案 0 :(得分:4)
关于项目结构和project.clj的一切看起来都很正常。
如果我想加载src / utils / general.clj怎么办:
这几乎总是通过require
或use
表达式来完成。虽然可以使用load-file
加载文件,但这需要您指定文件的路径(相对于启动JVM的位置)。 load
相对于类路径加载它,但实际上,当加载的文件是项目的一部分时,几乎从不使用它们。在这种情况下,您可以简单地require
他们。
我希望能够从其他源文件中请求或使用这些源文件:
这样做的预期方法是在名称空间中的ns表单中放置一个(:require [popco.core.acme :as acme])
语句,该名称空间要使用该命名空间中的函数。
如何从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表单中的这一点。