Quantcast

Binding Closure property not called as method

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Binding Closure property not called as method

Wujek Srujek
Hi. Why does this work:

c = { println 'works' }
c()

whereas this one doesn't:

def bind = new Binding(c: { println 'does not work' })
def t = { c() }
t.delegate = bind
t()

They both define a 'c' property in the binding which happens to be a closure. In the first case, the closure get's called as Groovy apparently tries to get the binding property and invoke it if it's a closure; in the latter, the delegate of the closure is a binding with a property 'c' that is a closure, but c() still doesn't work. Is this expected?

wujek
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

OC
Wujek,

On Mar 13, 2012, at 7:42 PM, Wujek Srujek wrote:

> whereas this one doesn't:
>
> def bind = new Binding(c: { println 'does not work' })
> def t = { c() }
> t.delegate = bind
> t()

Someone might correct my misunderstandings, but I believe that implicitly, c() means this.c(). There's no c in "this", which is your enclosing class. So, you need delegate.c().

But then, delegate.c() would mean to launch its method c, which method there is not. So, you need first to obtain the closure, then launch it:

def bind = new Binding(c: { println 'does work' })
def t = { (delegate.c)() }
t.delegate = bind
t()

> Is this expected?

This alas I can't answer -- most time I have no idea what to expect and what not :)

All the best,
---
Ondra Čada
OCSoftware:     [hidden email]               http://www.ocs.cz
private         [hidden email]             http://www.ocs.cz/oc




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

Wujek Srujek
I debugged this and there is actually an if i MetaClassImpl that checks if the 'this' object is a Script, and if so, a property with the name is retrieved and if it is a closure, it is called. (MetaClassImpl#invokePropertyOrMissing:1089 in Groovy 1.8.6-all from maven central)
I find it very inconsistent.

On Tue, Mar 13, 2012 at 8:04 PM, Ondřej Čada <[hidden email]> wrote:
Wujek,

On Mar 13, 2012, at 7:42 PM, Wujek Srujek wrote:

> whereas this one doesn't:
>
> def bind = new Binding(c: { println 'does not work' })
> def t = { c() }
> t.delegate = bind
> t()

Someone might correct my misunderstandings, but I believe that implicitly, c() means this.c(). There's no c in "this", which is your enclosing class. So, you need delegate.c().

But then, delegate.c() would mean to launch its method c, which method there is not. So, you need first to obtain the closure, then launch it:

def bind = new Binding(c: { println 'does work' })
def t = { (delegate.c)() }
t.delegate = bind
t()

> Is this expected?

This alas I can't answer -- most time I have no idea what to expect and what not :)

All the best,
---
Ondra Čada
OCSoftware:     [hidden email]               http://www.ocs.cz
private         [hidden email]             http://www.ocs.cz/oc




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

Jochen Theodorou
In reply to this post by OC
Am 13.03.2012 20:04, schrieb Ondřej Čada:

> Wujek,
>
> On Mar 13, 2012, at 7:42 PM, Wujek Srujek wrote:
>
>> whereas this one doesn't:
>>
>> def bind = new Binding(c: { println 'does not work' })
>> def t = { c() }
>> t.delegate = bind
>> t()
>
> Someone might correct my misunderstandings, but I believe that
> implicitly, c() means this.c(). There's no c in "this", which is your
> enclosing class. So, you need delegate.c().

The matter of "this" in a closure is a bit more complicated than usual.
Unqualified calls are part of the Closure MOP, meaning you can for
example use a delegate to redirect the call. If the delegate above had a
c() method it would surely work. That it does not work in the example
above looks a bit like a bug, but since it is a script I am not 100%
sure. scripts and classes differ a little. Anyway... a c() call anywhere
will cause a lookup like this: check if there is a method on "structure"
of that name. If not, call missingMethod, if that fails, look for a
property of that name. If that is a closure, call it... where the last
part might have been changed recently to always call.. I didn't check.
"structure" means in case of a normal class the class. In case of a
Closure, it means the Closure. The Closure has a - well I wouldn't call
it really simplified - maybe fixated - MOP, in which it will do a
certain lookup logic including the binding, the owner (which might be
the enclosing class or Closure) and the real "this", the enclosing class.

> But then, delegate.c() would mean to launch its method c, which
> method  there is not. So, you need first to obtain the closure, then launch it:
>
> def bind = new Binding(c: { println 'does work' })
> def t = { (delegate.c)() }
> t.delegate = bind
> t()

(delegate.c)() should work too, but is not needed.

bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

Jochen Theodorou
In reply to this post by Wujek Srujek
Am 13.03.2012 22:04, schrieb Wujek Srujek:
> I debugged this and there is actually an if i MetaClassImpl that checks
> if the 'this' object is a Script, and if so, a property with the name is
> retrieved and if it is a closure, it is called.
> (MetaClassImpl#invokePropertyOrMissing:1089 in Groovy 1.8.6-all from
> maven central)
> I find it very inconsistent.

can you fill a bug for this? I remember similar bugs, which we had
problems in reproducing. Could be that is because of the difference of
class and script here

bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

Cédric Champeau
In reply to this post by Jochen Theodorou
True that I'm not sure about the Script thing, but definitely looks like
a bug. I don't really see why { c() } would not work while the resolve
strategy is untouched, and given that { c.call() } works...

Le 14/03/2012 20:11, Jochen Theodorou a écrit :

> Am 13.03.2012 20:04, schrieb Ondřej Čada:
>> Wujek,
>>
>> On Mar 13, 2012, at 7:42 PM, Wujek Srujek wrote:
>>
>>> whereas this one doesn't:
>>>
>>> def bind = new Binding(c: { println 'does not work' })
>>> def t = { c() }
>>> t.delegate = bind
>>> t()
>>
>> Someone might correct my misunderstandings, but I believe that
>> implicitly, c() means this.c(). There's no c in "this", which is your
>> enclosing class. So, you need delegate.c().
>
> The matter of "this" in a closure is a bit more complicated than
> usual. Unqualified calls are part of the Closure MOP, meaning you can
> for example use a delegate to redirect the call. If the delegate above
> had a c() method it would surely work. That it does not work in the
> example above looks a bit like a bug, but since it is a script I am
> not 100% sure. scripts and classes differ a little. Anyway... a c()
> call anywhere will cause a lookup like this: check if there is a
> method on "structure" of that name. If not, call missingMethod, if
> that fails, look for a property of that name. If that is a closure,
> call it... where the last part might have been changed recently to
> always call.. I didn't check. "structure" means in case of a normal
> class the class. In case of a Closure, it means the Closure. The
> Closure has a - well I wouldn't call it really simplified - maybe
> fixated - MOP, in which it will do a certain lookup logic including
> the binding, the owner (which might be the enclosing class or Closure)
> and the real "this", the enclosing class.
>
>> But then, delegate.c() would mean to launch its method c, which
>> method  there is not. So, you need first to obtain the closure, then
>> launch it:
>>
>> def bind = new Binding(c: { println 'does work' })
>> def t = { (delegate.c)() }
>> t.delegate = bind
>> t()
>
> (delegate.c)() should work too, but is not needed.
>
> bye blackdrag
>


--
Cédric Champeau
SpringSource - A Division Of VMware
http://www.springsource.com/
http://twitter.com/CedricChampeau


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Binding Closure property not called as method

Wujek Srujek
In reply to this post by Jochen Theodorou
Here it is:

wujek

On Wed, Mar 14, 2012 at 8:13 PM, Jochen Theodorou <[hidden email]> wrote:
Am 13.03.2012 22:04, schrieb Wujek Srujek:

I debugged this and there is actually an if i MetaClassImpl that checks
if the 'this' object is a Script, and if so, a property with the name is
retrieved and if it is a closure, it is called.
(MetaClassImpl#invokePropertyOrMissing:1089 in Groovy 1.8.6-all from
maven central)
I find it very inconsistent.

can you fill a bug for this? I remember similar bugs, which we had problems in reproducing. Could be that is because of the difference of class and script here


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



Loading...