ITコンサルの日常

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

Objectクラスにインスタンスメソッドとクラスメソッド追加&呼び出し

Ruby#evalScriptletでObjectクラスにインスタンスメソッドとクラスメソッドを追加しておいてから、

  • Ruby#evalScriptletでメソッドを呼び出す
  • Ruby#getClass#newInstance#callMethodでインスタンスメソッドを呼び出す
  • Ruby#getClass#callMethodでクラスメソッドを呼び出す

を試してみる。

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

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

		// Objectクラスにインスタンスメソッドを追加
		String scriptlet = "class Object\n  def hoge(str)\n    'hoge: ' + str\n  end\nend\n";
		runtime.evalScriptlet(scriptlet);

		// Objectクラスにクラスメソッドを追加
		String scriptlet2 = "class Object\n  def self.moge(str)\n    'moge: ' + str\n  end\nend\n";
		runtime.evalScriptlet(scriptlet2);

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

		obj = runtime.evalScriptlet("Object.moge('from evalScriptlet')");
		System.out.println(obj.getClass().getName());
		System.out.println(obj);

		// Objectクラスを取得
		RubyClass rubyObject = runtime.getClass("Object");
		IRubyObject rubyObjectObj = rubyObject.newInstance(runtime.getCurrentContext(), new IRubyObject[0], Block.NULL_BLOCK);
		RubyString param = runtime.newString("from runtime.getClass");

		// インスタンスメソッドを呼んで、戻り値を取得する
		obj = rubyObjectObj.callMethod(runtime.getCurrentContext(), "hoge", param);
		System.out.println(obj.getClass().getName());
		System.out.println(obj);

		// クラスメソッドを呼んで、戻り値を取得する
		obj = rubyObject.callMethod(runtime.getCurrentContext(), "moge", param);
		System.out.println(obj.getClass().getName());
		System.out.println(obj);
	}
}

結果はこう。

org.jruby.RubyString
hoge: from evalScriptlet
org.jruby.RubyString
moge: from evalScriptlet
org.jruby.RubyString
hoge: from runtime.getClass
org.jruby.RubyString
moge: from runtime.getClass

普通にできてます。