试图理解隐含的Leiningen源路径/命名空间设置假设

时间:2013-11-02 00:43:32

标签: clojure leiningen

(对不起,这太长了。排除误解的时间很长,不是因为我想让你弄明白我的问题应该是什么。)

我理解Clojure名称空间的基础知识,并且文件开头的ns语句中列出的名称空间必须与目录层次结构中文件的位置匹配。我已经弄清楚了Leiningen自动设置搜索load的部分内容,以及它自动加载的部分内容,但......它仍然让我发疯。问题在于Leiningen似乎隐含地设置了一些东西,在Leiningen tutorialsample 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,更重要的是,我希望能够requireuse来自其他源文件的这些源文件。例如,如何从acme.clj中引用general.clj中的函数?我认为答案可能是在project.clj中:source-paths之后向序列添加条目,但我对应该去哪里感到困惑。

随意推荐任何东西。其他目录结构,对project.clj的根本性改变,无论如何。

1 个答案:

答案 0 :(得分:4)

关于项目结构和project.clj的一切看起来都很正常。

  • 如果我想加载src / utils / general.clj怎么办:
    这几乎总是通过requireuse表达式来完成。虽然可以使用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:
    你很可能永远不需要在那里放任何东西。 requireuse是适当的工具。他们已经能够找到/ src /下的所有文件,因为当leiningen启动java时,这些文件将在类路径中。您可以看到lein classpath函数使用的类路径。

ps:您也可以将requireuse作为函数调用(例如,形成REPL),但通常首选ns表单中的这一点。