Zweikopf (pronunciation) helps you to interoperate between Clojure and JRuby on JVM.
Add this line to your application's Gemfile:
gem 'zweikopf'
And then execute:
$ bundle
Or install it yourself as:
$ gem install zweikopf
For Clojure-driven projects, add this line to your project.clj
:
[zweikopf "1.0.0"]
For Ruby-driven ones, just add the following line to your Gemspec:
gem "zweikopf", "~> 1.0.0"
Transfroming from Clojure entities to Ruby ones is as easy as:
# Say you have a variable clojure_var that is a Clojure Hash: {:a 1 :b 2}
Zweikopf::Transformer.from_clj(clojure_var)
# => {:a => 1, :b => 2}
# Or an array: [1 2 3 4 5]
Zweikopf::Transformer.from_clj(clojure_var)
# => [1, 2, 3, 4, 5]
# Or something really wicked: {:a 1 :b {:c [{:d 2} {:e 3} {:f 4}]}}
Zweikopf::Transformer.from_clj(clojure_var)
# => {:a => 1, :b => {:c => [{:d => 2}, {:e => 3}, { :f => 4}]}}
And backwards:
# Say you have a variable ruby_var that is a Ruby Hash: {:a => 1, :b => 2}
Zweikopf::Transformer.from_ruby(ruby_var)
# => {:a 1 :b 2}
# Or an array: [1, 2, 3, 4, 5]
Zweikopf::Transformer.from_ruby(ruby_var)
# => [1 2 3 4 5]
# Or something really wicked: {:a => 1, :b => {:c => [{:d => 2}, {:e => 3}, { :f => 4}]}}
Zweikopf::Transformer.from_ruby(ruby_var)
# => {:a 1 :b {:c [{:d 2} {:e 3} {:f 4}]}}
When performing Ruby to Clojure transformation, you may leave out some space for customization:
class CustomTransformedEntry
def serializable_hash
{:c => 3, :d => 4}
end
end
Zweikopf::Transformer.from_ruby({:a => 1, :b => CustomTransformedEntry.new }) do |v|
if v.is_a?(CustomTransformedEntry)
v.serializable_hash
else
v
end
end
# => {:a 1 :b {:c 3 :d 4}}
With Clojure version everything is extremely simple:
(:require 'zweikopf.core)
;; You _must_ call it, otherwise Ruby Runtime won't get initialized.
(init-ruby-context)
;; To convert Clojure DS to Ruby, run:
(rubyize {:a 1 :b 2})
;; To convert Ruby DS to Clojure, run
(clojurize ruby-obj)
;; If you want to execute arbitrary Ruby code, use ruby-eval:
(ruby-eval "puts 'Hello World'") ;; Or any other portion of Ruby code you'd like to execute
;; In order to require a file:
(ruby-require "filename")
;; In order to load:
(ruby-load "filename")
;; Call a method on a Ruby object:
;; This will call `#to_hash` method on `ruby-obj`
(call-ruby ruby-obj :to_hash)
;; To set gem-path:
(set-gem-path "my-gem-path")
;; To set gem-home:
(set-gem-path "my-gem-home")
;; To add custom convertor from Ruby to Clojure, extend protocol Clojurize
;; For example, convertion of RubyTime class to java Date
(extend-protocol Clojurize
org.jruby.RubyTime
(clojurize [this]
(.toJava this java.util.Date)))
;; To add custom convertor from Clojure to Ruby, extend protocol Rubyize
;; For example, convertion of Clojure Keyword class to Ruby Symbol
(extend-protocol Rubyize
clojure.lang.Keyword
(rubyize [this]
(.fastNewSymbol ruby-runtime (name this))))
When using Rails and DateTime conversion, you should call DateTime#utc
before you can call #to_time
.
It's very easy to package all your gems in a Jar, if you decide to do so, you need to either use
the files that were extracted by the runtime (which is by itself quite tricky, and you may run into
some issues with Bundler, if you use it), alternative is to materialize (extract) your gems from
jar manually. We're not yet ready to open our sorce for jar extraction, but you can write up your
own quite quickly, using FileReader
, JarFile
and JarInputStream
files.
Other than that, JRuby/Clojure integration is very smooth and painless.
We highly recommend using target language convertor. If you pass rather small data structures to Ruby scripts, and return large portions back, use Clojure version. If you pass smaller amounts of data to Clojure code, and it returns larger cunks, use Ruby version of transformer.
Most of time 52% according to the rough estimate is spent while converting from ruby Symbol to clojure Keyword.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Copyright (C) 2012-2013 Alex Petrov and contributors.
Distributed under the Eclipse Public License, the same as Clojure.