読者です 読者をやめる 読者になる 読者になる

JRubyで遊ぼう(1) JavaからRubyを実行する

JRubyはPure Javaで書かれたRuby実装。一方、JavaではJava6からスクリプト言語との連携ができるようになった。つまり、JavaからPerlRubyを呼んだり、その逆ができるのだ。夢が広がりんぐである。そんななかで、Javaで書かれたJRubyはこの連携において非常に親和性が高い。ともあれ、やってみよう。

インストール

JRubyは通常のRubyインタプリタのように、スタンドアロンで実行できる。しかしここでは、Javaから呼び出すためだけにJRubyを入れる。
必要なのは、

の2つである。

jruby.jarは次のサイトから落とす。

JRuby
http://jruby.codehaus.org/

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しておいて、使用する間はメモリに確保しておくのがよさそうです。

参考

今回使用したソースは、下記のサイトから使用させていただきました。

JRuby Engine
http://www.pigumer.gr.jp/memo/2007/20070217_1.html

メモ

jruby.jarとjruby-complete.jarがあるが、違いは未調査。今回のはどちらでも動く。