【问题标题】:How do I import stuff from sibling files in clojure/cider/nrepl?如何从 clojure/cider/nrepl 中的兄弟文件导入内容?
【发布时间】:2016-08-08 12:55:52
【问题描述】:

我有一个 ~/src/proj/{foo,bar}.clj 的小项目,我正在使用 emacs、苹果酒和 nREPL 进行黑客攻击。在bar.clj 我做(def base-13-joke 42) 并且我希望foo.clj 中的代码引用bar.cljbase-13-joke。我该怎么做?


我当前的类路径(~/src/proj = /jonas/src/mine/code/move-the-box

/home/jonas/src/mine/code/move-the-box/target/classes
/home/jonas/.m2/repository/cider/cider-nrepl/0.11.0/cider-nrepl-0.11.0.jar
/home/jonas/.m2/repository/org/tcrawley/dynapath/0.2.3/dynapath-0.2.3.jar
/home/jonas/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar
/home/jonas/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar
/home/jonas/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
/usr/lib/jvm/java-7-openjdk-amd64/lib/tools.jar

我试过(add-classpath "file:///jonas/src/mine/code/move-the-box") 似乎没有效果,以及(cider.nrepl.middleware.util.java/add-classpath! "file:///home/jonas/src/mine/code/move-the-box") 抛出IllegalArgumentException array element type mismatch java.lang.reflect.Array.set (Array.java:-2)。那里发生了什么?

【问题讨论】:

    标签: clojure classpath cider nrepl


    【解决方案1】:

    如果您将多个 Clojure 源文件作为一个项目处理,那么使用 LeiningenBoot 等构建工具会获得很多好处。例如,您可以使用以下方法创建一个名为 myproject 的简单引导项目,其中包含多个源文件。

    首先,使用以下内容创建一个myproject 目录(无论在哪里):

    myproject
    ├── build.boot
    └── src
        └── myproject
            ├── bar.clj
            └── foo.clj
    

    Boot 将在执行任何其他操作之前运行您的 build.boot 文件(例如,运行您的一些代码、创建 JAR 或启动 REPL)。现在,您需要告诉 Boot 的是您的源文件将在 src 目录中,所以只需将此行添加到 build.boot

    (set-env! :source-paths #{"src"})
    

    bar.clj 中,输入您想从其他代码访问的定义:

    (ns myproject.bar)
    
    (def base-13-joke 42)
    

    然后,在foo.clj 中,您可以在ns 声明中使用:require 子句引用bar.clj

    (ns myproject.foo
      (:require [myproject.bar :as bar]))
    
    (defn make-joke []
      (println (Long/toString bar/base-13-joke 13)))
    

    仅此而已!当然,您可能想用您刚刚编写的代码实际 一些事情。 Boot 通过tasks 处理“做事”。让我们编写一个简单地运行项目中的功能之一的程序。

    当您想要定义一个使用 Boot 运行的任务时,您可以通过将定义该任务的代码添加到您的 build.boot 文件中来实现。不过,首先,由于我们要调用我们的一些主要代码(在本例中,是myproject.foo 命名空间中的make-joke 函数),我们需要require 那个代码。将此行添加到build.boot

    (require '[myproject.foo :as foo])
    

    现在我们可以定义一个简单的run 任务(同样在build.boot 中)来运行我们的函数:

    (deftask run []
      (with-pass-thru _
        (foo/make-joke)))
    

    with-pass-thru 业务只与 Boot 中的一些任务细节有关,您可以详细阅读 here

    执行任务非常容易。从项目根目录在命令行中运行它:

    $ boot run
    33
    

    Boot 还内置了一些任务。例如,如果您运行 boot repl,您将在 boot.user 命名空间中看到熟悉的 REPL 提示:

    boot.user=>
    

    此命名空间与 Boot 在其中执行 build.boot 脚本的命名空间相同,因此由于我们在 build.boot 中有一个 require 对应于 myproject.foo,因此我们可以在 REPL 中使用该命名空间:

    boot.user=> (foo/make-joke)
    33
    nil
    

    当然,你也可以require其他命名空间:

    boot.user=> (require '[myproject.bar :as bar])
    nil
    boot.user=> bar/base-13-joke
    42
    

    您可以使用 Boot 执行更多操作,例如重新加载代码和与 CIDER 交互,您可以在 Boot Wiki 中阅读所有相关信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 2014-10-13
      • 2019-07-01
      • 1970-01-01
      • 2021-10-05
      相关资源
      最近更新 更多