【问题标题】:How to load Clojure files from directory to REPL while preserving dependency order?如何在保留依赖顺序的同时将 Clojure 文件从目录加载到 REPL?
【发布时间】:2018-06-20 03:23:27
【问题描述】:

我的文件系统中有 2 个外部 Clojure 文件。(a.cljb.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 或任何其他构建工具(想以编程方式进行)。可能有一些库/代码 sn-p 向我显示需要按依赖顺序加载的文件。像 leiningen 这样的构建工具是如何实现这一点的?他们以某种方式做到这一点。

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您说不想使用 lein 或任何其他构建工具,这很好。所以你最好只是按照that article关于 Clojure 1.9 发布的最新 CLI 工具来组织你的代码。

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

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

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

      看看那篇文章,它真的很有帮助。

      【讨论】:

      • 仍然不能解决我的问题这种方法使用 CLI,我需要以编程方式进行。
      • 所以在这种情况下,在启动 REPL 时,您需要指定 .clj 文件的路径。检查该页面是否有“路径”短语:clojure.org/reference/repl_and_main
      • 遇到同样的错误,我应该也知道使用REPL路径的依赖顺序
      【解决方案3】:

      您不需要加载所有文件,只需加载依赖关系树的根文件即可。根据需要加载其他源文件。因此,如果命名空间 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 的人来说,这已经很重要了。

      【讨论】:

        【解决方案4】:

        如果您使用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 了解更多详细信息)。

        【讨论】:

        • 我的意思是,不使用 leiningen,我想以编程方式并仅使用核心 Clojure 库。或者它可以是任何其他库,向我显示应该按依赖顺序加载的 clojure 文件
        猜你喜欢
        • 2012-04-06
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 2013-09-04
        • 2011-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多