5

(对不起,这么长。排除误解,不是因为我想让你弄清楚我的问题应该是什么。)

我了解 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

这是 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 中定义的函数和记录类型都可用。我已经(通过反复试验)了解到:main popco.core.popcoproject.clj 中的“”导致 popco.clj 运行,这导致 REPL 留在popco.core.popco命名空间中。到现在为止还挺好。

以下是我的问题:

如果我想加载 src/utils/general.clj 或 src/popco/sims/sim1/sim1propns.clj 怎么办?我可以用 加载它们load-file,但我想load在 REPL 中使用,更重要的是,我希望能够从其他源文件requireuse这些源文件。例如,如何从 acme.clj 中引用 general.clj 中的函数?我认为答案可能是:source-paths在 project.clj 之后向序列中添加条目,但我对应该去那里的内容感到困惑。

随意推荐任何东西。其他目录结构,对 project.clj 的根本更改,等等。

4

1 回答 1

5

关于您的项目结构和 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:你也可以调用requireuse作为函数(例如形成 REPL),尽管通常首选 ns 形式。

于 2013-11-02T01:00:20.660 回答