groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Duncan Dickinson ...@duncan.dickinson.name>
Subject Re: Instance initializer blocks confused for a closure
Date Sat, 11 Jul 2015 06:47:29 GMT
Hi Blackdrag,

Thank you for your response - it clarifies the issue nicely. I like your idea of using ;{...}
and will note that as a safe approach to instance initialiser blocks. 

Cheers,

Duncan

> On 11 Jul 2015, at 16:25, Jochen Theodorou <blackdrag@gmx.org> wrote:
> 
> Am 11.07.2015 07:48, schrieb Duncan Dickinson:
> [...]
>> Should this be a Jira ticket (I couldn't see one), if only to document
>> it? It's something I noticed rather than something that upsets me.
> 
> the problem is the newline character, that in some cases is supposed to end the statement
and in other cases is supposed to be swallowed. The compiler can't always do the right thing
here and instance initializers suffer from that.
> 
>> *Example 1: Works.*
>> I declare two properties with no initial assignment. Assignment
>> performed in initializer block.
>> 
>> class Person1 {
>>     def id
>>     def name
>> 
>>     {
>>         id = 1
>>         name = 'Anonymous'
>>     }
>> }
>> 
>> Person1 p1 = new Person1()
>> println p1.dump()
> [...]
>> *Example 3: Causes **exception* groovy.lang.MissingMethodException: No
>> signature of method: Person3.Anonymous3() is applicable for argument
>> types: (Person3$_closure1)
>> 
>> class Person3 {
>>     def id
>>     def name = 'Anonymous3'
>> 
>>     {
>>         id = 3
>>     }
>> }
>> 
>> Person3 p3 = new Person3()
>> p3.dump()
> 
> imagine that foo {bar} is a method call. But the same goes for 'foo' {bar}. Which means
that def name = 'Anonymous3' {id=3} is also seen as method call for the right side.
> 
>> *Example 4: Works*
>> This is the same as Example 3 except I place a semicolon to explicitly
>> terminate the statement
> 
> yes, then it works, because then the compiler knows that this spacing is nothing that
connects that statement and the one before.
> 
>> *Example 5: Works*
>> Similar to Example 3 - I just place another statement after the
>> assignment and the initializer block isn't mistaken for a closure
>> 
>> class Person5 {
>>     def id
>>     def name = 'Anonymous5'
>>     def email
>> 
>>     {
>>         id = 5
>>     }
>> }
>> 
>> Person5 p5 = new Person5()
>> p5.dump()
> 
> that's basically the same as the first two examples. Because of "def" there is no danger
of accidentally seeing you code part as method call, thus there is no problem. At this place
a method call could only ever happen as part of an assignment anyway.
> 
> My suggestion would be based on your example 4... write the initializer block like this:
;{....} I mean with a starting semicolon. Then you never ever should have that problem again.
> 
> As for a JIRA for this... I doubt we can ever solve this without doing language changes.
It is more a language limitation, than a bug
> 
> bye blackdrag
> 
> -- 
> Jochen "blackdrag" Theodorou
> blog: http://blackdragsview.blogspot.com/
> 

Mime
View raw message