Search code examples
groovymetaprogrammingexpandometaclass

Groovy expando metaclass


I've developed a Class that has some methods that augment Integer, it mainly lets me do this:

def total = 100.dollars + 50.euros

Now I have to extend Integer.metaClass doing something like this:

Integer.metaClass.getDollars = {->
    Money.Dollar(delegate)
}

I tried putting that at the bottom of the file, before the Money class declaration, but the compiler says that a class Named Money already exists, I know why it happens (because groovy creates a class with the name of the file with an empty static void main to run this code).

I also tried using a static block inside the class like this:

static {
    Integer.metaClass.getDollars = {->
        Money.Dollar(delegate)
    }
}

This neither works.

A third solution would be to change the file name (like MoneyClass.groovy) and keep the class name (class Money) but that seems a bit weird.

Is there anything else I can do? Thanks.


Solution

  • Just put it in any method of any class maybe a bean TypeEnhancer.groovy:

    public class TypeEnhancer {
      public void start() {
        Integer.metaClass.getDollars() = {-> Money.Dollar(delegate) }
      }
    
      public void stop() {
        Integer.metaClass = null
      }
    }
    

    Just create and initalize by calling start(): new TypeEnhancer().start();. To disable the enhancement, call new TypeEnhancer().stop();. The bean can also used as Spring bean.