1

JavaスクリプトエンジンとRubyを試していますが、rubyスクリプトでいくつかのインスタンス変数を設定するのに問題があります。これは、Rubyについての私の理解の欠如、またはスクリプトエンジンでのrubyクラスの使用方法についての私の理解の欠如である可能性があります。次のコードで:

public class App {

    public static void main( String[] args ) throws Exception{
        ScriptEngineManager sm = new ScriptEngineManager();
        ScriptEngine se = sm.getEngineByName("jruby");

        StringBuilder sb = new StringBuilder();
        sb.append("class Test\n");
        sb.append("   attr_accessor :a, :b\n");
        sb.append("   def str\n");
        sb.append("      \"#{a}, #{b} is a test.\"\n");
        sb.append("   end\n");
        sb.append("end\n");
        sb.append("o = Test.new\n");

        Object o = se.eval(sb.toString());  

        se.put("@a", "A");
        se.put("@b", "B");

        System.out.println( ((Invocable) se).invokeMethod(o, "str"));
    }
}

出力は「A、Bはテストです」になると思います

代わりに、出力は「、テスト」です。

このコードで変数a、bをどのように設定する必要がありますか?

編集:明確にするために、理想的には、このStringBuilderに変数を追加して変数を設定したくありません-これは単なる説明のためです。実際には、いくつかのソースからスクリプトをロードし、後でそのRubyオブジェクトにプロパティを設定してメソッドを呼び出したいと思います。私は他の誰もが知っているいくつかの重要なステップを見逃していると確信しています:)。Gareth Davisの回答のおかげで、バインディングとグローバル変数を正常に使用できることがわかりましたが、それがすべてのスクリプトで機能するとは限りません。適切な記事が見つからなかったため、「helloworld」タイプの使用法を超える優れた記事へのリンクをいただければ幸いです。

2番目の編集:これは機能する最終的なコードであり、私が知っていた重要な行が欠落している必要があります:)-

public class App {

    public static void main( String[] args ) throws Exception{

        //Must set this property if you want to call eval multiple times!
        System.setProperty("org.jruby.embed.localvariable.behavior", "persistent");
        ScriptEngineManager sm = new ScriptEngineManager();
        ScriptEngine se = sm.getEngineByName("jruby");

        StringBuilder sb = new StringBuilder();
        sb.append("class Test\n");
        sb.append("   attr_accessor :a, :b\n");
        sb.append("   def str\n");
        sb.append("      \"#{a}, #{b} is a test.\"\n");
        sb.append("   end\n");
        sb.append("end\n");
        sb.append("o = Test.new\n");

        Object o = se.eval(sb.toString());

        se.eval("o.a = \"A\"");
        se.eval("o.b = \"B\"");

        System.out.println( ((Invocable) se).invokeMethod(o, "str"));
    }
}
4

1 に答える 1

1

それはそのようには機能しません。a & b の値を設定する唯一の方法は、o.a = 'A'andを評価することo.b = 'B'です。

最初の解決策は、スクリプトを修正して値を入力することです。

    sb.append("o.a = 'A'\n");
    sb.append("o.b = 'B'\n");
    sb.append("o");
    Object o = se.eval(sb.toString());

github.com で実用的な例を作成しました

質問に沿って、次を使用できます(@Mick Searのクレジット):

System.setProperty("org.jruby.embed.localvariable.behavior", "persistent"); 

// .. snip

Object o = se.eval(sb.toString());

se.eval("o.a = 'A'");
se.eval("o.b = 'B'");

System.out.println( ((Invocable) se).invokeMethod(o, "str"));
于 2012-05-21T21:50:32.363 に答える