How do I dynamically invoke methods in Groovy?
Asked Answered
S

2

13

At runtime I'm grabbing a list of method names on a class, and I want to invoke these methods. I understand how to get the first part done from here: http://docs.codehaus.org/display/GROOVY/JN3535-Reflection

GroovyObject.methods.each{ println it.name }

What I can't seem to find information on is how to then invoke a method once I've grabbed its name.

What I want is to get here:

GroovyObject.methods.each{ GroovyObject.invokeMethod( it.name, argList) }

I can't seem to find the correct syntax. The above seems to assume I've overloaded the default invokeMethod for the GroovyObject class, which is NOT the direction I want to go.

Schipperke answered 3/1, 2012 at 17:5 Comment(0)
S
20

Groovy allows for dynamic method invocation as well as dynamic arguments using the spread operator:

def dynamicArgs = [1,2]
def groovy = new GroovyObject()
GroovyObject.methods.each{ 
     groovy."$it.name"(staticArg, *dynamicArgs)
}

Reference here

Question answered here.

Schipperke answered 3/1, 2012 at 17:16 Comment(3)
While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Superscribe
The provided link is dead. Does this link similar? groovy-lang.org/metaprogramming.html#_dynamic_method_namesCycling
I updated the link to point to an archived version of the original, now dead link. Happy metaprogramming!Schipperke
I
23

Once you get a MetaMethod object from the metaclass, you can call invoke on it. For example:

class MyClass {
    def myField = 'foo'
    def myMethod(myArg) { println "$myField $myArg" }
}
test = new MyClass()
test.metaClass.methods.each { method ->
    if (method.name == 'myMethod') {
        method.invoke(test, 'bar')
    }
}

Alternatively, you can use the name directly:

methodName = 'myMethod'
test."$methodName"('bar')
Incrassate answered 3/1, 2012 at 18:51 Comment(2)
Is there a way to check if the method exists without iterating over metaClass.methods?Lette
@AlexanderSuraphel The respondsTo() method will tell you if the method exists. Example: if (test.respondsTo(methodName)) { ... }Incrassate
S
20

Groovy allows for dynamic method invocation as well as dynamic arguments using the spread operator:

def dynamicArgs = [1,2]
def groovy = new GroovyObject()
GroovyObject.methods.each{ 
     groovy."$it.name"(staticArg, *dynamicArgs)
}

Reference here

Question answered here.

Schipperke answered 3/1, 2012 at 17:16 Comment(3)
While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Superscribe
The provided link is dead. Does this link similar? groovy-lang.org/metaprogramming.html#_dynamic_method_namesCycling
I updated the link to point to an archived version of the original, now dead link. Happy metaprogramming!Schipperke

© 2022 - 2024 — McMap. All rights reserved.