groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: Get reference to enclosing closure
Date Tue, 21 Nov 2017 18:32:51 GMT
I am not saying I am getting the question fully...

but what you want is

def c = { return XY }
assert c() == c

something like that? Extend BytecodeExpersion and do a "ALOAD 0". No 
guarantees that this will work forever though. In the future there might 
be no closure class anymore.

Oh and if I got you wrong, and you want a reference to the enclosing 
context, that would be the owner:

def x = this
def c = { return {owner}}
assert c()() == c
assert c.owner == x

bye Jochen

On 20.11.2017 21:27, Leonard Brünings wrote:
> 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
> 
> Here is the gist:
> 
> This snippet
> 
> d|ef 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
> 
> Do you have any ideas on how to fix this elegantly?
> 
> - Cheers
> Leonard
> 
> ||||||
> 
> ||
> 


Mime
View raw message