Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

binding and closures groovy

I don't know how to use binding with closures in Groovy. I wrote a test code and while running it, it said, missing method setBinding on the closure passed as parameter.

void testMeasurement() {
    prepareData(someClosure)
}
def someClosure = {
  assertEquals("apple", a)
}


  void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()

  }
like image 938
prabha Avatar asked Jul 13 '10 11:07

prabha


1 Answers

This works for me with Groovy 1.7.3:

someClosure = {
  assert "apple" == a
}
void testMeasurement() {
  prepareData(someClosure)
}
void prepareData(testCase) {
  def binding = new Binding()
  binding.setVariable("a", "apple")
  testCase.setBinding(binding)
  testCase.call()
}
testMeasurement()

In this script example, the setBinding call is setting a in the scripts binding (as you can see from the Closure documentation, there is no setBinding call). So after the setBinding call, you can call

println a

and it will print out "apple"

So to do this in the class, you can set the delegate for the closure (the closure will revert back to this delegate when a property cannot be found locally) like so:

class TestClass {
  void testMeasurement() {
    prepareData(someClosure)
  }

  def someClosure = { ->
    assert "apple" == a
  }

  void prepareData( testCase ) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.delegate = binding
    testCase.call()
  }
}

And it should grab the value fro a from the delegate class (in this case, a binding)

This page here goes through the usage of delegate and the scope of variables in Closures

Indeed, instead of using a Binding object, you should be able to use a simple Map like so:

  void prepareData( testCase ) {
    testCase.delegate = [ a:'apple' ]
    testCase.call()
  }

Hope it helps!

like image 54
tim_yates Avatar answered Sep 21 '22 13:09

tim_yates