ITコンサルの日常

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

JavaからFixturesを使ってみる

昨日のFixturesをRails外で使ってみるは、これの伏線なのでした。


で、JavaからJRubyを使ってRubyのライブラリを使う方法ですが、
色々やったところ、org.jruby.Ruby#evalScriptletってのを使うとできるようです。
org.jruby.runtime.load.LoadService#requireってのだと、うまく行きませんでした。。

import java.io.*;
import java.util.*;

import org.jruby.*;
import org.jruby.ast.*;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.*;

public class CallRuby
{
	public static void main(String[] args) throws Exception
	{
		Ruby runtime = Ruby.newInstance();

		BufferedReader br = new BufferedReader(new FileReader("hoge.rb"));
		StringBuffer sb = new StringBuffer();
		String str;
		while((str = br.readLine()) != null)
		{
			sb.append(str + "\n");
		}
		br.close();

		System.out.println(sb.toString());
		runtime.evalScriptlet(sb.toString());
	}
}

コンパイル

javac -classpath E:\jruby-1.1.4\lib\jruby.jar CallRuby.java

実行

java -Djruby.home=%JRUBY_HOME% -classpath %JRUBY_HOME%\lib\jruby.jar;. CallRuby

結果

insert
select all
1/test
2/hoge
3/hoge0
4/hoge1
5/hoge2
6/hoge3
7/hoge4
8/hoge5
9/hoge6
10/hoge7
11/hoge8
12/hoge9
delete
select all
finish

JavaからFixturesを使ってみる - ちょっとだけすっきり書けた

import java.io.FileInputStream;
import org.jruby.Ruby;
import org.jruby.runtime.Block;

public class CallRuby
{
	public static void main(String[] args) throws Exception
	{
		Ruby runtime = Ruby.newInstance();
		runtime.parseFile(
			new FileInputStream("hoge.rb")
			, "<hoge>"
			, runtime.getCurrentContext().getCurrentScope()
		).interpret(
			runtime
			, runtime.getCurrentContext()
			, runtime.getCurrentContext().getFrameSelf()
			, Block.NULL_BLOCK
		);
	}
}

引数は無理矢理文字列組み立てればできないことはないけど、戻り値はどうやって取得するのだろうか。。

JavaからRubyを呼んで、戻り値を取得する

evalScriptletの戻り値を使えば良かったらしい。そのまんまじゃん。

import org.jruby.Ruby;
import org.jruby.runtime.builtin.IRubyObject;

public class CallRuby
{
	public static void main(String[] args) throws Exception
	{
		Ruby runtime = Ruby.newInstance();

		// Kernelモジュールにtestメソッド(文字列'hoge'を返す)を追加
		String scriptlet = "module Kernel\n  def test\n    'hoge'\n  end\nend\n";
		runtime.evalScriptlet(scriptlet);

		// testメソッドを呼んで、戻り値を取得する
		IRubyObject obj = runtime.evalScriptlet("test");
		System.out.println(obj.getClass().getName());
		System.out.println(obj);
	}
}

結果はこう。

org.jruby.RubyString
hoge

RubyString型で、文字列"hoge"が返されていることが分かります。