我正在试验 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”类型用法的好文章的链接,因为我没有找到任何像样的文章。
第二次编辑:这是工作的最终代码,我知道必须缺少关键行:)-
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"));
}
}