Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JRuby类和Java脚本引擎意外的结果_Java_Ruby_Jruby_Jsr223 - Fatal编程技术网

JRuby类和Java脚本引擎意外的结果

JRuby类和Java脚本引擎意外的结果,java,ruby,jruby,jsr223,Java,Ruby,Jruby,Jsr223,我正在试验Java脚本引擎和Ruby,在Ruby脚本中设置一些实例变量时遇到了问题。这可能是我对Ruby缺乏了解,或者我对如何在脚本引擎中使用Ruby类缺乏了解。使用以下代码: public class App { public static void main( String[] args ) throws Exception{ ScriptEngineManager sm = new ScriptEngineManager(); ScriptEngi

我正在试验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的回答,我发现我可以成功地使用绑定和全局变量,但这并不适用于所有脚本。我真的很感激任何超出“hello world”类型用法的好文章链接,因为我还没有找到任何合适的链接

第二次编辑:这是正在运行的最终代码,其中有一行我知道肯定丢失了:)-


那样不行。设置a&b值的唯一方法是计算
o.a='a'
o.b='b'

第一种解决方案是修改脚本以填充值,因此:

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

根据问题,可以使用以下内容(归功于@Mick Sear):


那样不行。设置a&b值的唯一方法是计算
o.a='a'
o.b='b'

第一种解决方案是修改脚本以填充值,因此:

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

根据问题,可以使用以下内容(归功于@Mick Sear):


谢谢-我希望能够用java参数化脚本,而不是在执行脚本之前乱搞脚本。如果脚本存储在一个地方,参数存储在另一个地方,那么我觉得您最初的方法更有用。Gareth,我尝试了绑定方法,它适用于全局变量,但恐怕它不适用于Ruby类的实例变量。我曾尝试使用绑定将“o”绑定回上下文,但没有成功。无论如何,谢谢。好的,最后解决了。缺少的关键行是:System.setProperty(“org.jruby.embed.localvariable.behavior”,“persistent”);这使得多个eval使用相同的状态。然后,您可以在原始帖子中使用该方法:se.eval(“o.a=\“a\”);作为一个单独的调用。Gareth,既然你给我指出了正确的方向,如果你想重新编辑你的答案并将该系统属性粘贴进去,我会将你的答案标记为正确。谢谢-我希望能够用java参数化脚本,而不是在执行它之前乱搞脚本。如果脚本存储在一个地方,参数存储在另一个地方,那么我觉得您最初的方法更有用。Gareth,我尝试了绑定方法,它适用于全局变量,但恐怕它不适用于Ruby类的实例变量。我曾尝试使用绑定将“o”绑定回上下文,但没有成功。无论如何,谢谢。好的,最后解决了。缺少的关键行是:System.setProperty(“org.jruby.embed.localvariable.behavior”,“persistent”);这使得多个eval使用相同的状态。然后,您可以在原始帖子中使用该方法:se.eval(“o.a=\“a\”);作为一个单独的呼叫。Gareth,既然你给我指出了正确的方向,如果你想重新编辑你的答案并将系统属性粘贴进去,我会将你的答案标记为正确。
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"));