Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 563
M. Jessup Avatar asked Apr 30 '10 15:04

M. Jessup


2 Answers

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.

like image 81
Dónal Avatar answered Nov 15 '22 10:11

Dónal


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

like image 44
tim_yates Avatar answered Nov 15 '22 09:11

tim_yates