Friday, June 20, 2008

Very un-groovy

I really like Groovy as a language, but it does have its flaws. My colleague and I came across some very strange syntax and weird behavior surrounding GPathResult. GPathResult is fine and dandy for a read-only view of an object graph, but it does support some write operations. The documentation says you should only use it for read operations and then gives examples of how to write.

Unfortunately, those write operations are a bit broken. You can add nodes but the changes won't be reflected by the iterators or size() method. There is not method to remove a node, but you can effectively do so by replacing it with an empty closure. Unfortunately there are some downsides that as well because in some cases the nodes act like a linked list and if you replace one in the middle, you lose all the nodes after it.

Probably the worst thing about GPathResult is the overridden plus operator. I have never seen the plus operator overridden to perform a mutation on the object, but that's what GPathResult does. Take this from a mock Grails plugin for example:

class AGrailsPlugin {
def doWithWebDescriptor = { xml ->
def mappingElement = xml.'servlet'
mappingElement[mappingElement.size() - 1] + {
'servlet' {
'servlet-name'('a')
'servlet-class'('com.discorp.web.AServlet')
}
}
}
}

That actually adds a new servlet node right after the last servlet node in the tree. That has to be to most un-groovy syntax I have seen in Groovy. It's not at all obvious what going on and it's very hackish. Unfortunately I don't think there is any other way to perform that function in Grails, though I have a ticket open for it.

No comments: