caffeine_inquisitor
caffeine_inquisitor

Reputation: 727

GroovyInterceptable & introduced attribute

I have a class that implements GroovyInterceptable, and I thought it should make all method invocation to go through the 'invokeMethod'. But I find that this is not the case.

class Test implements GroovyInterceptable{

    String name

    @Override
    Object invokeMethod(String name, Object args) {
        def metaMethod = this.metaClass.getMetaMethod(name, args)
        return metaMethod.invoke(this, "BAR")
    }

    public static void main(String[] args) {
        Test.metaClass.NEWATTRIBUTE = null

        def test = new Test()
        test.NEWATTRIBUTE = "MEOW1"
        println test.NEWATTRIBUTE   // shouldnt this be BAR ?


        test.setNEWATTRIBUTE("MEOW2")
        println test.NEWATTRIBUTE // prints 'BAR'


        // much simpler example ....

        test.name = "MOOO"
        println test.name // shouldnt this be BAR ?

        test.setName("MOOO")
        println test.name // prints 'BAR'
    }
}

I think I read somewhere, that

test.NEWATTRIBUTE = "MEOW1"

doesnt really access the field directly. Groovy will still call the setter method - and hence the invokeMethod should get invoked, shouldnt it?

Thanks

Alex

Upvotes: 1

Views: 776

Answers (2)

caffeine_inquisitor
caffeine_inquisitor

Reputation: 727

WillP: Thanks a lot. Here is the complete code:

class Test implements GroovyInterceptable{

    String name

    @Override
    Object invokeMethod(String name, Object args) {
        def metaMethod = this.metaClass.getMetaMethod(name, args)
        return metaMethod.invoke(this, "BAR")
    }

    void setProperty(String prop, val) {
        getMetaClass().setProperty(this, prop, "BAR2");
    }

    public static void main(String[] args) {
        Test.metaClass.NEWATTRIBUTE = null

        def test = new Test()
        test.NEWATTRIBUTE = "MEOW1"
        println test.NEWATTRIBUTE   // prints BAR2


        test.setNEWATTRIBUTE("MEOW2")
        println test.NEWATTRIBUTE // prints BAR


        test.name = "MOOO"
        println test.name // prints BAR2

        test.setName("MOOO")
        println test.name // prints BAR
    }
}

as it turns out, setProperty() is called regardless the class implements GroovyInterceptable or not. But invokeMethod() is only called when the class implements GroovyInterceptable

Upvotes: 0

Will
Will

Reputation: 14539

When setting a property, Groovy invokes setProperty. Add this method to the class:

void setProperty(String prop, val) {
    System.out.println "set property $prop with $val"
}

Upvotes: 1

Related Questions