groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <eric.mil...@thomsonreuters.com>
Subject RE: Get reference to enclosing closure
Date Mon, 20 Nov 2017 20:29:58 GMT
I think "this" or "getThisObject()" should really be "delegate" or "getDelegate()".

From: Leonard Brünings [mailto:groovy-dev@bruenings-it.net]
Sent: Monday, November 20, 2017 2:27 PM
To: dev@groovy.apache.org
Subject: Get reference to enclosing closure


Hi,

I'm Leonard from the Spock framework team. Guillaume suggested that I write to the dev-list
with this problem.

Some context:

Spock has a method `with(Object, Closure)` in its Specification class that sets the object
as the delegate of the closure and transforms,
every call inside the closure to an implicit assertion.

given:

      def person = new Person(name: "Peter", age: 28)

expect:

      with(person) {

          name == 'Peter'

          age == 28

      }

This worked fine for properties, however for single methods like `contains` it didn't work.

The initial problem is described here https://github.com/spockframework/spock/pull/606<https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_spockframework_spock_pull_606&d=DwMDaQ&c=4ZIZThykDLcoWk-GVjSLmy8-1Cr1I4FWIvbLFebwKgY&r=tPJuIuL_GkTEazjQW7vvl7mNWVGXn3yJD5LGBHYYHww&m=Fa8Q9YcX7hY9VbwfwahFaxYu0kY_r2a9tvNUcGXmQSk&s=q_R3dw-m9pIZzvCwtx3GC4Mm0pBAF3QIJ5lFVjTIF7k&e=>

Here is the gist:

This snippet



def list = [1, 2]

with(list) {

  contains(1)

}



transforms in AST (simplified) to

def list = [1, 2]

with(list) {

  SpockRuntime.verifyMethodCondition(this, "contains", [1])

}



then when the AST is written to bytecode it gets transformed again

def list = [1, 2]

with(list) {

  SpockRuntime.verifyMethodCondition(this.getThisObject(), "contains", [1])

}

The problem is that the `contains` is now invoked on the containing `Specification` instead
of the `List`.

With the aforementioned PR it was changed to this

def list = [1, 2]

with(list) {

  SpockRuntime.verifyMethodCondition(this.each(groovy.lang.Closure.IDENTITY), "contains",
[1])

}



This "fix" now broke the nesting of `with` blocks as described here: https://github.com/spockframework/spock/pull/782<https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_spockframework_spock_pull_782&d=DwMDaQ&c=4ZIZThykDLcoWk-GVjSLmy8-1Cr1I4FWIvbLFebwKgY&r=tPJuIuL_GkTEazjQW7vvl7mNWVGXn3yJD5LGBHYYHww&m=Fa8Q9YcX7hY9VbwfwahFaxYu0kY_r2a9tvNUcGXmQSk&s=M5zC-i1pBw89T8iQDueDfncXWUr7YsR1IynIed9NqiI&e=>

Do you have any ideas on how to fix this elegantly?

- Cheers
Leonard
Mime
View raw message