如何在保留依赖顺序的同时将Clojure文件从目录加载到REPL?
我的文件系统中有两个外部Clojure文件。(a.clj和b.clj) /Users/e/.somedir/a.clj:如何在保留依赖顺序的同时将Clojure文件从目录加载到REPL?,clojure,Clojure,我的文件系统中有两个外部Clojure文件。(a.clj和b.clj) /Users/e/.somedir/a.clj: (ns a (:require [b])) (b/printt) (ns b) (defn printt [] (println "aaaa")) /Users/e/.somedir/b.clj: (ns a (:require [b])) (b/printt) (ns b) (defn printt [] (println "aaaa")) 问题是我希望能够
(ns a (:require [b]))
(b/printt)
(ns b)
(defn printt [] (println "aaaa"))
/Users/e/.somedir/b.clj:
(ns a (:require [b]))
(b/printt)
(ns b)
(defn printt [] (println "aaaa"))
问题是我希望能够将这些文件加载到我的REPL(保留依赖顺序)
如果我首先加载a.clj,我会得到以下异常:
(clojure.main/load-script)/Users/e/.somedir/a.clj”)
:
CompilerException java.io.FileNotFoundException:在类路径上找不到b_uinit.class或b.clj,正在编译:(/Users/e/.somedir/a.clj:1:1)
如果我先加载b.clj,则没有问题
那么我如何计算出这个依赖关系顺序并加载b.clj首先,假设这是一个复杂的依赖关系图,是否有代码示例
p.S:我不想使用leiningen或任何其他构建工具(希望以编程方式进行)。可能会有某种库/代码片段向我显示需要按依赖顺序加载的文件。像leiningen这样的构建工具是如何实现这一点的?他们会以某种方式完成这项工作。如果您使用
lein
设置项目,这很容易。下面是一个示例项目fred
。要创建简单项目,只需键入:
> lein new app fred
> cd fred
> cp src/fred/core.clj src/fred/second.clj
现在看来是这样的:
fred
└── src
├── fred
├── core.clj
└── second.clj
有两个源文件core.clj
和second.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)
尽管这并不完美,而且可能会陷入混乱状态(有关更多详细信息,请参阅)。如果您使用
lein
设置项目,这很容易。下面是一个示例项目fred
。要创建简单项目,只需键入:
> lein new app fred
> cd fred
> cp src/fred/core.clj src/fred/second.clj
现在看来是这样的:
fred
└── src
├── fred
├── core.clj
└── second.clj
有两个源文件core.clj
和second.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)
尽管这并不完美,而且可能会陷入混乱状态(有关更多详细信息,请参阅)。您不需要加载所有文件,只需加载依赖关系树的根文件即可。根据需要加载其他源文件。因此,如果名称空间A需要名称空间B,而名称空间B需要名称空间C,那么您只需: (加载“com/example/A.clj”) 和B.clj和C.clj自动加载 此外,由于您没有使用构建工具,因此需要注意以下几点: 1) 您需要确保源文件文件夹结构反映了命名空间声明,因此'com.example.A'的ns应该位于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的人来说太多了。您不需要加载所有文件,只需加载依赖关系树的根文件。根据需要加载其他源文件。因此,如果名称空间A需要名称空间B,而名称空间B需要名称空间C,那么您只需: (加载“com/example/A.clj”) 和B.clj和C.clj自动加载 此外,由于您没有使用构建工具,因此需要注意以下几点: 1) 您需要确保源文件文件夹结构反映了命名空间声明,因此'com.example.A'的ns应该位于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的人来说太多了。你说不想使用lein或任何其他构建工具,这很好。因此,您最好根据Clojure 1.9发布的最新CLI工具来组织代码 简单地说,在您的文件夹中,创建另一个
src
文件夹并将所有.clj文件放在那里。系统将自动找到它们。例如:
└── your-project
├── deps.edn # your dependencies
└── src
└── a.clj
└── b.clj
然后,在项目顶部,只要运行cli
,REPL就会出现。在那里,您可能还需要模块
看看那篇文章,它会很有帮助。你说不想使用lein或任何其他构建工具,这很好。因此,您最好根据Clojure 1.9发布的最新CLI工具来组织代码 简单地说,在您的文件夹中,创建另一个
src
文件夹并将所有.clj文件放在那里。系统将自动找到它们。例如:
└── your-project
├── deps.edn # your dependencies
└── src
└── a.clj
└── b.clj
然后,在项目顶部,只要运行cli
,REPL就会出现。在那里,您可能还需要模块
看看那篇文章,它真的会很有帮助。我想我首先找到了解决方案,然后我创建了拓扑顺序对名称空间进行排序。