Может ли привязка GroovyShell передать ссылку на объект при выполнении setVariable?

Мне интересно, есть ли способ для объекта Binding хранить ссылку на объект вместо его копирования?

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

К сожалению, он печатает «тест».

Есть ли способ сделать это в 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 создается в одном потоке, а затем я передаю его как ссылку на объект Runnable, который затем вызывает методы action, validate и afterTest. Если я закомментирую вызов setVariable в конструкторе и раскомментирую вызов в validate, он будет работать нормально.

Возможно ли, что это проблема параллелизма? В afterTestScript я просто хочу напечатать строку ответа.


person Krystian    schedule 11.02.2012    source источник


Ответы (2)


Я получал это, когда создавал новые темы самостоятельно. Как только я начал использовать пул потоков, проблема исчезла.

Вполне возможно, что это произошло из-за какого-то другого изменения, но это единственное изменение, которое я мог видеть, мешающее groovy shell.

В конце концов мы перестали использовать groovy shell для оценки строк и начали анализировать их в сценарии для их запуска. Это был огромный прирост производительности.

person Krystian    schedule 16.02.2012

Суть вашей проблемы на самом деле связана с тем, что ваша ссылка на объект изменяется после ее установки. если вы хотите изменить его после назначения, вам понадобится объект-оболочка. Например. вместо

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)
person Brent Fisher    schedule 27.08.2014