Использование класса JRuby, поставляемого в драгоценном камне от Clojure

Я довольно простая необходимость использовать класс Ruby из Clojure. Усложняющими факторами являются то, что класс поставляется в драгоценном камне. Оптимальным подходом было бы настроить файл проекта Leiningein в соответствии с:

(project foo ""
  ...
  :dependencies [[clojure ...]
                 [jruby ...  ]])

Аналогично, я бы предпочел просто проверить драгоценный камень и его зависимости в локальном каталоге репо. Поэтому из моего идеального использования будет:

(ns bar.baz
  (require [jruby.something :as jruby])

(def obj (jruby/CreateAnInstance "TheGemClass"))

(def result (jruby/CallAMethod obj "method_name" some args))

Спасибо.

Ответ 1

Вот краткий список шагов для получения hello-world gem с использованием JRuby и Clojure и нескольких ссылок. Фактически, этапы составят только короткий эскиз того, как материал из ссылок может собраться вместе (с некоторыми project.clj записями). Первая ссылка, Haml на Clojure веб-приложение в блоге Yoko Harada (@yokolet), использует несколько иной способ, чтобы позвонить в JRuby, но включает ключевое замечание о том, как писать строки require("...") для использования с JRuby и драгоценными камнями в пути к классам.

  • Добавьте [org.jruby/jruby-complete "1.6.7.2"] к вашему :dependencies и получите Leiningen зависимости.

  • Создайте каталог gems в корне проекта и добавьте его в :resource-paths в project.clj. Это требует Leiningen 2. См. Leiningen source для правильного формата.

  • Say

    # see reference 4
    GEM_HOME=gems GEM_PATH=gems java -jar ~/.m2/repository/org/jruby/jruby-complete/1.6.7.2/jruby-complete-1.6.7.2.jar -S gem install hello-world
    

    в корне проекта.

  • Запустите сервис REPL по вашему выбору с помощью GEM_HOME и GEM_PATH, как указано выше. (Я тестировал это с помощью lein2 swank.)

  • Скажите в REPL следующее:

    ;;; see reference 2, first snippet
    (let [runtime (JavaEmbedUtils/initialize (list))
          evaler  (JavaEmbedUtils/newRuntimeAdapter)]
      (doseq [ruby-expr ["require('rubygems')"
                         "require('gems/hello-world-1.2.0/lib/hello-world')"]]
        (.eval evaler runtime ruby-expr)))
    
  • Посмотрите на возвращаемое значение nil, а также пару строк, распечатанных на терминале, с которых была запущена служба REPL.

Литература: