Как импортировать данные из родственных файлов в clojure/cider/nrepl?

У меня есть небольшой проект с ~/src/proj/{foo,bar}.clj, над которым я работаю с emacs, cider и nREPL. В bar.clj я делаю (def base-13-joke 42) и хочу, чтобы код в foo.clj ссылался на base-13-joke bar.clj. Как мне это сделать?


Мой текущий путь к классам (с ~/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). Что там происходит?


person Jonas Kölker    schedule 16.04.2016    source источник


Ответы (1)


Если вы работаете с несколькими исходными файлами Clojure как с одним проектом, вы получите много преимуществ от использования инструмента сборки, такого как Leiningen или Boot. Например, вот как можно создать простой загрузочный проект с именем 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.clj, используя предложение :require в объявлении ns:

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

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

И это все, что нужно! Конечно, вы, вероятно, захотите что-то сделать с кодом, который вы только что написали. Boot обрабатывает «выполнение задач» через задачи. Давайте напишем такой, который просто запускает одну из функций вашего проекта.

Если вы хотите определить задачу для запуска с помощью Boot, вы можете сделать это, добавив код для определения этой задачи в свой файл build.boot. Во-первых, поскольку мы собираемся вызывать часть нашего основного кода (в данном случае функцию make-joke в пространстве имен myproject.foo), нам нужно require этот код. Добавьте эту строку в build.boot:

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

Теперь мы можем определить простую задачу run (опять же, в 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, поэтому, поскольку у нас есть require вместо myproject.foo в 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, о чем вы можете прочитать в Загрузочная вики.

person Sam Estep    schedule 16.04.2016