sato
sato

Reputation: 101

Groovy CliBuilder: any method defined?

I'm very new to Groovy. Very simple question about the code found in CliBuilder.

http://docs.groovy-lang.org/latest/html/gapi/index.html?overview-summary.html

def cli = new CliBuilder(name:'ls')
cli.a('display all files')
cli.l('use a long listing format')
cli.t('sort by modification time')
def options = cli.parse(args)
assert options // would be null (false) on failure
assert options.arguments() == ['*.groovy']
assert options.a && options.l && options.t

The CliBuilder class behaves as knowing whatever methods we want to call in advance. By what Groovy's feature it can be supported?

Upvotes: 0

Views: 136

Answers (1)

Mene
Mene

Reputation: 3799

This is called Runtime metaprogramming.

If you want to create your own class with "dynamic methods", the easiest way is to implement the GroovyInterceptable interface and add the invokeMethod method to your class.

class Interception implements GroovyInterceptable {

    def definedMethod() { }

    def invokeMethod(String name, Object args) {
        'invokedMethod'
    }
}

Whenever a method is called on an instance if the class Interception, invokeMethod is called instead. Note that this is also true for methods actually defined in the class (e.g. definedMethod)

You can use the metaClass to call the actual method like this

class Interception implements GroovyInterceptable {

    def definedMethod() { }

    def invokeMethod(String name, Object args) {
        if (name == "actualMethod") {
            return metaClass.invokeMethod(this, name, args)
        }
        return "invokedMethod: $name($args)"
    }

    def actualMethod() {
        return 'hello there'
    }
}

Here a call to actualMethod still goes through invokeMethod, however invokeMethod contains logic to call the actual method.

There are some other ways (see link on top) to acomplish similar behavior, but I found this to be the easiest.

Note that runtime metaprogramming is incompatible with @CompileStatic unless you add a TypeCheckingExtension to mitigate this.

Run Example

Upvotes: 1

Related Questions