Jochen,

On 3. 4. 2016, at 22:29, Jochen Theodorou <blackd...@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

Reply via email to