JRubyをコマンドライン上ではなく、Javaのプログラム中から呼び出して使う方法を調べた。
- 使用したJRubyのバージョン: 9.1.2.0
JRubyを使うJavaコードのコンパイル、実行
JRubyを使ったJavaコードをコンパイルするには、-cp
(クラスパス)オプションで.jarファイルを指定してコンパイルする:
javac -cp .:jruby.jar Foo.java |
実行にも同じ.jarファイルを指定して
java -cp .:jruby.jar Foo |
などとする。
文字列をeval
Javaの文字列として持っているRubyコードを実行するには Ruby.evalScriptlet が使える:
import org.jruby.Ruby; |
- Ruby.newInstance でJrubyのインスタンスを生成して使う
Rubyのコードをファイルから読み込んで実行
適当なRubyのコードが書かれたファイル
puts "foobar" |
を読み込んで実行するには
import org.jruby.Ruby; |
- ScriptingContainer#runScriptlet
- 他にも
InputStream
やReader
を受け取るオーバーロードされたメソッドがある
JRubyからJavaの静的メソッドを呼び出す
import org.jruby.Ruby; |
Java::クラス名
でJavaのクラスにアクセス- なにもしなくても透過的に呼び出せるし、引数や戻り値も自動変換、超楽チン
JRubyからJavaのインスタンスを生成してメソッド呼び出し
適当なJavaのクラスがあったとして
public class Foo { |
それをRubyから生成しメソッドを呼び出す:
import org.jruby.Ruby; |
- 普通にRubyで定義したクラスと同様に
new
して呼び出せる、すげぇ
JavaからJRubyのメソッドを呼び出す
import org.jruby.Ruby; |
- ScriptingContainer#callMethod で呼び出せる
- 戻り値は
Object
型
- 戻り値は
JRubyからブロックを渡して、Javaから呼び出す
import org.jruby.Ruby; |
- RubyProc型の引数を指定するとブロックが受け取れる
- Blockではない
- getRuntimeでRubyインスタンスが取り出せるので、それを使ってあれこれする
- getCurrentContextのコンテキストをそのまま使っていいのかどうかは不明…
- ブロックが省略されてもいい場合には、Javaのオーバーロードを使うのか?
Javaの配列やリストを受け渡す
複雑なオブジェクトの受け渡し:
import java.util.ArrayList; |
- Rubyの配列のように扱える、ダックタイピングとはいえ便利すぐる…
- 同様にJavaの
Map
もRubyのHash
として扱える
パース
import org.jruby.Ruby; |
コンパイル・実行
import org.jruby.Ruby; |
起動時間
- JRubyの起動にはそこそこ時間がかかる
Ruby.newInstance()
を呼び出すだけのコードでも、6秒前後の時間がかかる