M. Jessup
M. Jessup

Reputation: 8222

Remove Single Metaclass Method

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?

Upvotes: 7

Views: 2880

Answers (2)

tim_yates
tim_yates

Reputation: 171084

As a followup, I posted a bug report here:

https://issues.apache.org/jira/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

Upvotes: 2

Dónal
Dónal

Reputation: 187529

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.

Upvotes: 7

Related Questions