4

我有一个小项目~/src/proj/{foo,bar}.clj,我正在使用 emacs、苹果酒和 nREPL 进行黑客攻击。在bar.clj我做(def base-13-joke 42),我希望代码foo.clj引用bar.clj's base-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")which 似乎没有效果,以及(cider.nrepl.middleware.util.java/add-classpath! "file:///home/jonas/src/mine/code/move-the-box")which throws IllegalArgumentException array element type mismatch java.lang.reflect.Array.set (Array.java:-2)。那里发生了什么事?

4

1 回答 1

4

如果您将多个 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,您可以在声明中引用bar.cljusing:require子句ns

(ns myproject.foo
  (:require [myproject.bar :as bar]))

(defn make-joke []
  (println (Long/toString bar/base-13-joke 13)))

这就是它的全部!当然,您可能希望对刚刚编写的代码进行实际操作。Boot 通过tasks处理“做事” 。让我们编写一个简单地运行项目中的功能之一的程序。

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

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

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

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

with-pass-thru业务仅与 Boot 中的一些任务细节有关,您可以在此处详细阅读。

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

$ boot run
33

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

boot.user=>

这个命名空间与 Boot 执行build.boot脚本的命名空间相同,所以由于我们有一个requirefor myproject.fooin build.boot,我们可以在 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中阅读所有相关内容。

于 2016-04-16T17:04:34.743 回答