JRubyはPure Javaで書かれたRuby実装。一方、JavaではJava6からスクリプト言語との連携ができるようになった。つまり、JavaからPerlやRubyを呼んだり、その逆ができるのだ。夢が広がりんぐである。そんななかで、Javaで書かれたJRubyはこの連携において非常に親和性が高い。ともあれ、やってみよう。
インストール
JRubyは通常のRubyインタプリタのように、スタンドアロンで実行できる。しかしここでは、Javaから呼び出すためだけにJRubyを入れる。
必要なのは、
の2つである。
jruby.jarは次のサイトから落とす。
jruby-engine.jarは次のサイトから落とす。
- jsr-engines - java.net
- https://scripting.dev.java.net/servlets/ProjectDocumentList
落とすのはjsr223-engines.zip。jarは、jruby/buildの中にある。
以上の2つのjarにクラスパスを通せばOK(JREを1.6以上にするのを忘れずに)。
サンプル
public class JRubyTest { public static void main(String[] args) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("jruby"); try { engine.put("msg", "Hello"); engine.eval("puts $msg\n$msg = 'Bye'"); Object result = engine.get("msg"); System.out.println(result.getClass().getName() + ": " + result); } catch (ScriptException e) { e.printStackTrace(); } } }
実行結果は次の通り。
Hello java.lang.String: Bye
RubyがJavaのなかで動いてる…! 感動ですね。夢が広がりますね。
しかし実行の際、1秒くらい停止時間がある。これが気になるので、自作のStopWatchクラスを使って時間を計ってみる。
public class JRubyTest { public static void main(String[] args) { StopWatch watch = new StopWatch(); System.out.println("JRubyTest#main: " + watch.get()); ScriptEngineManager manager = new ScriptEngineManager(); System.out.println("JRubyTest#main: " + watch.get()); ScriptEngine engine = manager.getEngineByName("jruby"); System.out.println("JRubyTest#main: " + watch.get()); try { for (int i = 0; i < 10; i++) { engine.put("msg", "Hello"); engine.eval("puts $msg\n$msg = 'Bye'"); Object result = engine.get("msg"); System.out.println(result.getClass().getName() + ": " + result); System.out.println("JRubyTest#main: " + watch.get()); } } catch (ScriptException e) { e.printStackTrace(); } } }
実行結果は次の通り。
JRubyTest#main: 0 JRubyTest#main: 31 JRubyTest#main: 1047 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0 Hello java.lang.String: Bye JRubyTest#main: 0
ちなみに数字の単位はミリ秒なので、どうやら
ScriptEngine engine = manager.getEngineByName("jruby");
に1秒ほどかかっているみたいです。はじめに一度getEngineしておいて、使用する間はメモリに確保しておくのがよさそうです。