Thursday, October 10, 2013

Groovy Closures, and line endings

I've been using Groovy for a while now so when I was coding the following and it was crapping out at the compiler stage I was confused

Date newDate =  (Date)toObject("Problem converting imDate", new StringBuilder(), [:], {
            println "Parse date = $it";
            df.parse(it.date) }
)
private Object toObject(def errMsg, StringBuilder errors, def row, Closure c){
        try{
            Object ret = c.call(row);
            if(!ret)
                throw new RuntimeException("Returned null")
        }catch (Exception e){
            errors.append("$errMsg :-${e.getMessage()}\n")
            null
        }
    }


This is simply creating a method with a Closure parameter and calling it with an anonymous closure. Simple stuff.. But the compiler doesn't like it.

BTW I did look up using Types and Generics so I didn't need to cast the response, but looking into it it doesn't appear to be possible to define the return type of a Closure.. so little bit of a gap there in groovy.

Changing the closure from anonymous to defined fixed the problem
def c= {
            println "Parse date = $it";
            df.parse(it.date) }

Date newDate =  (Date)toObject("Problem converting imDate", new StringBuilder(), [:],c)

But I didn't want to do this, as I was calling the method multiple times and it messed up my Feng Shui.

So the problem, apparently was the casting. It seems to expect the object to cast to appear on the same line as the cast (Date) directive. Wrapping the method call in  parenthesis  fixed the problem.

Date newDate =  (Date)(toObject("Problem converting imDate", new StringBuilder(), [:], {
            println "Parse date = $it";
            df.parse(it.date) }
))