Confused about invokeMethod in Groovy MOP

Review the following Groovy code first:

class Car {

    def check() { System.out.println "check called..." }

    def start() { System.out.println "start called..." }

}

Car.metaClass.invokeMethod = { String name, args ->

    System.out.print("Call to $name intercepted... ")

    if (name != 'check') {
        System.out.print("running filter... ")
        Car.metaClass.getMetaMethod('check').invoke(delegate, null)
    }

    def validMethod = Car.metaClass.getMetaMethod(name, args)
    if (validMethod != null) {
        validMethod.invoke(delegate, args)
    } else {
        Car.metaClass.invokeMissingMethod(delegate, name, args)
    }
}

car = new Car()
car.start()

      

Output:

Call to start intercepted... running filter... check called...
start called...

      

According to Groovy's method dispatching mechanism, I think the start method in Car should be called directly, and not be intercepted by the invokeMethod in the Car metaclass. Why is the startup method intercepted by the method call? How is the invokeMethod method called when calling a method on an object?

If you can give me some in-depth explanations about Groovy's Method Dispatching Mechanism (MOP), I'd appreciate it.

+3


source to share


1 answer


In short, you are not using the standard meta class, so you will not get the standard Groovy MOP.



Car.metaClass.invokeMethod = {

will allow Car to have ExpandoMetaClass as a metaclass. This metaclass uses the invokeMethod method, which you provide as an open block (for example, you) to intercept calls. This is very different from the definition of invokeMethod in the class itself.

+4


source







All Articles