Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

grails metaprogramming

My understanding is that there are two obvious places in a Grails app where one can do meta-programming:

  1. The init closure of Bootstrap.groovy
  2. The doWithDynamicMethods closure of a plugin

The meta-programming I'm referring to here should be visible throughout the application, typical examples include adding (or replacing) methods of 3rd party classes.

String.metaClass.myCustomMethod = { /* implementation omitted */ }

The disadvantage of (1), is that the metaprogramming won't be applied when the application is dynamically reloaded. The disadvantage of (2) is that I need to create and maintain an entire plugin just for the sake of a little metaprogramming.

Is there a better place to do this kind of metaprogramming?

Update

Following Ted's suggestion below, I added the following class to src/groovy

package groovy.runtime.metaclass.java.lang

/**
 * Adds custom methods to the String class
 */
class StringMetaClass extends DelegatingMetaClass {

    StringMetaClass(MetaClass meta) {
        super(meta)
    }

    Object invokeMethod(Object object, String method, Object[] arguments) {
        if (method == 'hasGroovy') {
            object ==~ /.*[Gg]roovy.*/
        } else {
            super.invokeMethod object, method, arguments
        }
    }
}

Then restarted the app and ran the following code in the Grails console:

assert 'mrhaki loves Groovy'.hasGroovy()

I got the following exception

groovy.lang.MissingMethodException: No signature of method:
java.lang.String.hasGroovy() is applicable for argument types: () values: []

Am I doing something wrong or is there a reason this doesn't work in a Grails app?

like image 384
Dónal Avatar asked May 25 '10 08:05

Dónal


People also ask

What is Groovy metaprogramming?

Runtime metaprogramming enables us to alter the existing properties and methods of a class. Also, we can attach new properties and methods; all at runtime. Groovy provides a few methods and properties that help to alter the behavior of a class at runtime.

Does Groovy require semicolon?

​ semicolons are optional in Groovy, you can omit them, and it's more idiomatic to remove them.

How do I create a constructor in Groovy?

To create an object by using positional parameters, the respective class needs to declare one or more constructors. In the case of multiple constructors, each must have a unique type signature. The constructors can also added to the class using the groovy. transform.


1 Answers

Check out the Delegating MetaClass, it's part of groovy and makes your metaclass changes part of the metaclass that's used on every instance of that class right from the start. It operates on a simple convention and even works outside of grails.

like image 188
Ted Naleid Avatar answered Oct 11 '22 13:10

Ted Naleid