17 Nov 2008, 21:20
Generic-user-small

Robert Kuhar (11 posts)

While reviewing the Chapter 12 example TestMethodInvocation.groovy, I was left with the impression that metaClass method modifications can’t ever be “undone”. That is to say, there is no way to tell the expandometaclass to forget about my closure overrides and let the object just revert to its original behavior. Is this correct? Here’s the code that I tried and failed with, along with some inline questions. Please explain.

  void testInterceptedExistingMethodCalled() {
    /*
     * What is the scope of this metaClass modification?  Just this method or
     * from here on out?  I guess for that matter, how do you undo a metaClass
     * modification once you've applied it?  Also, within my interceptor, is
     * there any way to do something like super() the original method?
     */
    def closure = { -> 'intercepted' }
    AGroovyObject.metaClass.existingMethod2 = closure
    def obj = new AGroovyObject()
    assertEquals 'intercepted', obj.existingMethod2()

    // This all fails, why can't I undo my metaClass modifications?
    // AGroovyObject.metaClass.existingMethod2 = null
    // obj = new AGroovyObject()
    // assertEquals 'existingMethod2', obj.existingMethod2()
  }

Bob

18 Nov 2008, 12:01
Venkatsubramaniam_pragsmall

Venkat Subramaniam (84 posts)

Currently the answer is no. I am sure that will change in the future. This is one reason, if you can, modify the method on an instance instead of on a class. That way, your modification does not affect all instances of a class. Modifying at an object level is also useful in the case of testing—it gives you isolation.

18 Nov 2008, 19:14
Generic-user-small

Robert Kuhar (11 posts)

Thanks for the reply, Venkat. I think what keeps throwing me is the “more than one way to accomplish your goal” in groovy. Regardless, groovy is looking pretty damn cool for the dynamic behavior we are trying to bring to our application.

19 Nov 2008, 02:10
Venkatsubramaniam_pragsmall

Venkat Subramaniam (84 posts)

Bob, I agree on both counts. I hope some of that will get “standardized” in a future revision and it certainly is darn cool to have this capability along with seamless integration with Java.

26 Mar 2009, 21:27
Generic-user-small

Greg Bridges (1 post)

I use GroovySystem.metaClassRegistry.removeMetaClass() to clean out metadata changes to a class.

09 Apr 2010, 03:19
Generic-user-small

Fanny Aenvie (1 post)

one may also consider using ProxyMetaClass -> http://groovy.codehaus.org/Using+the+Proxy+Meta+Class

  You must be logged in to comment