如何在保留依赖顺序的同时将Clojure文件从目录加载到REPL?

时间:2018-01-10 21:15:34

标签: clojure

我的文件系统中有2个外部Clojure文件。( a.clj b.clj

/Users/e/.somedir/a.clj:

(ns a (:require [b]))

(b/printt)

/Users/e/.somedir/b.clj:

(ns b)

(defn printt [] (println "aaaa"))

问题是我希望能够将这些文件加载​​到我的REPL(保留依赖顺序

如果我首先加载 a.clj ,我会收到此异常:

(clojure.main/load-script "/Users/e/.somedir/a.clj")

CompilerException java.io.FileNotFoundException: Could not locate b__init.class or b.clj on classpath., compiling:(/Users/e/.somedir/a.clj:1:1)

如果我首先加载 b.clj ,则没有问题。

那么我怎么能想出这个依赖顺序并首先加载 b.clj ,想象一下这是一个复杂的依赖图,是否有代码示例?

P.S :我不想使用leiningen或任何其他构建工具(想以编程方式执行)。可能有一些类型的库/代码片段向我显示需要按依赖顺序加载的文件。 leiningen这样的构建工具如何实现这一目标?他们以某种方式做到了。

4 个答案:

答案 0 :(得分:1)

您不需要加载所有文件,只需加载依赖关系树的根文件。根据需要加载其他源文件。因此,如果命名空间A需要命名空间B而命名空间B需要命名空间C,那么您只需:

(load" com / example / A.clj")

和B.clj和C.clj会自动加载。

此外,由于您未使用构建工具,因此您需要注意以下几点:

1)您需要确保您的源文件文件夹结构镜像您的命名空间声明,因此ns为' com.example.A'应该在像src / com / example / A.clj这样的文件夹结构中。如果你不知道Clojure无法知道依赖项在文件系统中的位置。

2)使用特定的类路径启动正在运行的Clojure REPL。如果' src'上面的文件夹没有在类路径上定义,Clojure也不知道它。所以要小心将该文件夹添加到类路径中:java -jar clojure-1.9.0.jar -cp [需要在此处包含你的src文件夹] clojure.main

最后一点,没有像Leiningen这样的构建工具运行意味着你需要成为java类路径的专家并理解Clojure的依赖模型。对于想要学习Clojure的人来说,这是非常重要的。

答案 1 :(得分:1)

你说不想使用lein或任何其他构建工具,那没关系。因此,您最好根据that article组织代码,了解Clojure 1.9发布的最新CLI工具。

简而言之,在您的文件夹中,创建另一个src文件夹并将所有.clj文件放在那里。系统会自动找到它们。例如:

└── your-project
    ├── deps.edn   # your dependencies
    └── src
        └── a.clj
        └── b.clj

然后,在项目的顶部,只需运行cli,就会出现REPL。在那里,您可能也需要您的模块。

看看那篇文章,它会有所帮助。

答案 2 :(得分:0)

如果使用lein设置项目,这很容易。这是一个示例项目fred。要创建一个简单的项目,只需输入:

> lein new app fred
> cd fred
> cp src/fred/core.clj  src/fred/second.clj

现在看起来像这样:

fred
└── src
    ├── fred
        ├── core.clj
        └── second.clj

包含2个源文件core.cljsecond.clj。添加你的功能:

> cat src/fred/core.clj 

(ns fred.core)

(defn aaa [& args]
  (println "aaa - enter")
  (println "aaa - exit"))


> cat src/fred/second.clj 

(ns fred.second
  (:require [fred.core :as fc]))

(defn bbb [& args]
  (println "bbb - enter")
  (fc/aaa)
  (println "bbb - exit"))

然后,您可以使用lein repl

访问这两者
 > lein repl
Clojure 1.9.0

fred.core=> (aaa)
aaa - enter
aaa - exit
nil
fred.core=> (require '[fred.second :as fs])
nil
fred.core=> (fs/bbb)
bbb - enter
aaa - enter
aaa - exit
bbb - exit
nil
fred.core=> 

您还可以使用以下变体重新加载命名空间及其依赖项:

(require '[fred.second :as fs] :reload-all)

虽然这并不完美,但可能陷入困惑状态(详见How to reload a clojure file in REPL)。

答案 3 :(得分:0)

我想我首先找到了解决方案,我创建了dependency graph然后我按照拓扑顺序对命名空间进行了排序,所以这就是我一直在寻找的东西。现在我可以按顺序加载 Clojure文件(增加依赖顺序)。