views:

69

answers:

2

I've been starting to learn Groovy and am currently looking at the metaclass functionality. I have seen the examples of adding a new method, and removing all methods, but nothing about removing a single method. For example:

String.metaClass.foo = {delegate.toUpperCase()}
String.metaClass.bar = {delegate.toLowerCase()}

with the obvious side-effects. Now I have seen that you can say

String.metaClass = null

To remove all of the methods. I would expect one could say something along the lines of

String.metaClass.foo = null

to remove String.foo(), but have String.bar() remain, however this statement does not seem to have any effect. Is there a way to say method foo() should no longer be defined, without effecting bar() or any other added methods?

+2  A: 

If you search this webpage for "remove method" it says that you should be able to remove a method using the exact syntax you've proposed above. But I tested it, and you're right, it doesn't seem to work.

A workaround is to assign a closure that throws MissingMethodException, which is what happens by default when you call a method that doesn't exist, e.g.

// Add method
String.metaClass.foo = {delegate.toUpperCase()}

// Remove method
def removeMethod = {throw new MissingMethodException()}
String.metaClass.foo = removeMethod

Admittedly, this is not the most pleasing solution.

Don
A: 

As a followup, I posted a bug report here:

http://jira.codehaus.org/browse/GROOVY-4189

And the documentation has been changed now

See the bug report for the reason this was never implemented

Don's answer is the best way around this

tim_yates