ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

JRuby on Java6 Scripting

参考URL1: JRuby Engine
参考URL2: Java Scripting Programmer's Guide

とりあえずjrunscriptで動かしてみる

jrunscript -classpath %JRUBY_HOME%\lib\jruby.jar;%JRUBY_HOME%\lib\jruby-engine.jar -l ruby

ちょっと遊んでみた。

jruby> puts 'Hello, world!'
Hello, world!
jruby> [1,2,3]
123
jruby> [1,2,3].each do |item|
:1: <STDIN>:1: , unexpected end-of-file (SyntaxError)

script error: org.jruby.exceptions.RaiseException: <STDIN>:1: , unexpected end-o
f-file

jruby> [1,2,3].each { |item| puts "item = #{item}" }
item = 1
item = 2
item = 3
123
jruby>

jirbと違って、複数行にまたがる文は書けないらしい。痛し。
普通にjirb使えって感じ。
終わるコマンドがない(?)ので、Ctrl+Cで終了。

まずはHello, world!

import java.io.*;
import javax.script.*;

public class CallRubyScripting
{
	public static void main(String[] args) throws Exception
	{
		// JRubyエンジンを初期化
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("jruby");
   
		// Rubyスクリプトを実行
		engine.eval("puts 'Hello, world!'");
	}
}
コンパイル

javac -classpath E:\jruby-1.1.4\lib\jruby.jar;E:\jruby-1.1.4\lib\jruby-engine.jar CallRubyScripting.java

実行

java -Djruby.home=E:\jruby-1.1.4 -classpath E:\jruby-1.1.4\lib\jruby.jar;E:\jruby-1.1.4\lib\jruby-engine.jar;. CallRubyScripting

結果
Hello, world!

メソッドを呼び出す

import java.io.*;
import javax.script.*;

public class CallRubyScripting2
{
	public static void main(String[] args) throws Exception
	{
		// JRubyエンジンを初期化
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("jruby");
   
		// Rubyスクリプトを実行
		engine.eval("puts");

		Invocable inv = (Invocable)engine;
		inv.invokeFunction("puts", "Hello, world!");
	}
}
結果
Hello, world!

戻り値を取得する

import java.io.*;
import javax.script.*;

public class CallRubyScripting3
{
	public static void main(String[] args) throws Exception
	{
		// JRubyエンジンを初期化
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("jruby");
   
		// Rubyスクリプトを実行
		engine.eval("def add(a,b) a+b end");
		Invocable inv = (Invocable)engine;
		Object obj = inv.invokeFunction("add", 1, 2);

		System.out.println("Result = " + obj);
	}
}
結果
Result = 3

evalしてから、Invocableにキャストっていう手続きが、なんとも違和感ありますが。。
普通にJRuby APIをたたいた方が、自然に書けるし、できることも多そう。
まあ、スクリプトってまとめてしまった時点で、ある程度の犠牲はやむを得ないのかも。