在执行setVariable时,GroovyShell绑定可以传递对象的引用吗?

时间:2012-02-11 14:44:10

标签: groovy groovyshell

我想知道Binding对象是否有办法存储对象的引用,而不是复制一个对象?

Binding b = new Binding()
String test = "test"
b.setVariable("sth", test)
test = "blah"
GroovyShell gs = new GroovyShell(b)
gs.evaluate("print(sth)")

不幸的是它会打印“test”。

有没有办法在groovy中做到这一点?

编辑:

我给出的例子是错误的,太简单了。

我认为我的问题发生是因为我在一个线程中实例化对象并在另一个线程中运行脚本。

class Test {


[...] // field declarations

    public Test(String name, String url, def params, String validateScript, String afterTestScript, GroovyShell shell) {

[...] //just assigning params to fields

        shell.setVariable("current", this)
    }


    void action() {


       response = "something"

    }

    void validate() {
        //shell.setVariable("current", this)
    }

    void afterTest() {
        if (afterTestScript) shell.evaluate(afterTestScript)
    }

}

因此Test对象是在一个Thread中创建的,然后我将它作为对Runnable对象的引用传递,然后该对象调用actionvalidateafterTest方法。 如果我在构造函数中注释掉setVariable的调用并取消注释validate中的调用,那么它将正常工作。

它是否可能是并发'问题'? 在afterTestScript中,我只想打印响应字符串。

2 个答案:

答案 0 :(得分:0)

我在自己创建新线程时得到了这个。 一旦我开始使用线程池,问题就消失了。

很有可能,这是因为其他一些变化,但这是我唯一能看到干扰groovy shell的变化。

最后我们停止使用groovy shell来评估字符串,并开始将它们解析为脚本来运行它们。这是一个巨大的性能提升。

答案 1 :(得分:0)

问题的本质实际上是由于在设置对象引用后更改了对象引用。如果你想在分配后更改它,那么你需要一个包装器对象。例如。而不是

String test = "test"
b.setVariable("sth", test)
test = "blah"
GroovyShell gs = new GroovyShell(b)

使用

class MyWapper {
  public String myText
  public MyWrapper(String text){
   this.myText = text;
  }
}

MyWrapper test = new MyWrapper("test")
b.setVariable("sth", test)
test.myText = "blah"
GroovyShell gs = new GroovyShell(b)