Max
Max

Reputation: 3914

Groovy stops working when methodMissing() is implemented

import groovy.xml.MarkupBuilder
class Foo {
    Foo() {}
    String boo() {
        def writer = new StringWriter()
        def xml = new MarkupBuilder(writer)
        xml.records() {
            car(name:'HSV Maloo', make:'Holden', year:2006) {
                country('Australia')
                record(type:'speed', 'Production Pickup Truck with speed of 271kph')
            }
        }
        println writer
    }
    def methodMissing(String methodName, args) {
        println "Get called"
    }
}

Foo a = new Foo()
a.boo()

Result:

Get called
<records />

Without implementing methodMissing(), result:

<records>
  <car name='HSV Maloo' make='Holden' year='2006'>
    <country>Australia</country>
    <record type='speed'>Production Pickup Truck with speed of 271kph</record>
  </car>
</records>

I'm scratching my head bleeding now, what did I miss here?

Upvotes: 1

Views: 77

Answers (1)

tim_yates
tim_yates

Reputation: 171144

The problem is that when boo() is called, it creates a MarkupBuilder and eventually hits:

        car(name:'HSV Maloo', make:'Holden', year:2006) {

This checks for a car method in your class, and if one isn't found, it checks for one in the delegate of the closure (the MarkupBuilder). The MarkupBuilder catches this, and generates an xml node.

However, you have defined methodMissing, so when it checks your class for the car method, it finds one and uses that instead (does nothing)

To fix this, you can specifically ask for the MarkupBuilder to be used by calling xml.car(), xml.country(), etc:

String boo() {
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    xml.records() {
        xml.car(name:'HSV Maloo', make:'Holden', year:2006) {
            xml.country('Australia')
            xml.record(type:'speed', 'Production Pickup Truck with speed of 271kph')
        }
    }
    println writer
}

Upvotes: 1

Related Questions