groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From OC <...@ocs.cz>
Subject Re: static propertyMissing in an interface
Date Sun, 03 Apr 2016 21:09:19 GMT
Jochen,

On 3. 4. 2016, at 22:29, Jochen Theodorou <blackdrag@gmx.org> wrote:

> On 03.04.2016 17:33, OC wrote:
> [...]
>> ===
>> 6 /tmp> <q.groovy
>> class q {
>>  static main(av) {
>>    ExpandoMetaClass.enableGlobally()
>>    Root.metaClass.static.propertyMissing={ name ->
>>      String getter="get${name.capitalize()}"
>>      def body={-> "<$name in $delegate>" }
>>      delegate.metaClass.static."$getter"=body
>>      body.call() // same problem with body(); delegate."$getter"() would work though
>>    }
>>    println "- ${Root.weird}"
>>  }
>> }
>> interface Root {}
>> 7 /tmp> groovy q.groovy
>> Caught: groovy.lang.MissingMethodException: No signature of method: java.io.StringWriter.capitalize()
is applicable for argument types: () values: []
>> groovy.lang.MissingMethodException: No signature of method: java.io.StringWriter.capitalize()
is applicable for argument types: () values: []
>> 	at q$_main_closure1.doCall(q.groovy:5)
>> 	at q.main(q.groovy:10)
>> 8 /tmp>
> 
> so I misunderstood... it was not, that somehow body was not recognized as closure or
such, it is that the execution of  code inside fails. capitalize() is a method on CharSequence,
StringWriter is no CharSequence, so the call fails. Did you add such a method yourself? if
not, you need to convert to String first.

Convert what?

I call the capitalize method only once, on the name argument of the propertyMissing closure.
That is/should be always a String, should it not? Or is there a valid case where this argument
would be something else?

Besides the problem disappears if the "body()" or "body.call()" call gets replaced by "delegate."$getter"()",
which is sort of weird, for delegate."$getter" actually contains the very body closure :-O

It looks like the way the body closure captures the name variable is... weird: it seems when
body.call() is performed, the propertyMissing closure gets called again, this time with a
StringWriter for "name", in a way which is completely obscure to me:

===
14 /tmp> <q.groovy      
class q {
 static main(av) {
   ExpandoMetaClass.enableGlobally()
   Root.metaClass.static.propertyMissing={ String name ->
     def body={-> "<$name in $delegate>" }
     body.call()
   }
   println "- ${Root.weird}"
 }
}
interface Root {}
15 /tmp> groovy q.groovy
Caught: groovy.lang.MissingMethodException: No signature of method: q$_main_closure1.doCall()
is applicable for argument types: (java.io.StringWriter) values: [- <weird in ]
...
16 /tmp> 
===

Thank you very much and all the best,
OC


Mime
View raw message