Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy - check if param is a function

In JavaScript, this is how I check if a function parameter is a function:

function foo ( p ) {
    if ( typeof p === 'function' ) {
        p();
    }
    // ....
}

How can I do the same in Groovy?

like image 875
darksoulsong Avatar asked Jan 18 '18 11:01

darksoulsong


People also ask

How do I know the type of variable in Groovy?

You can use the getClass() method to determine the class of an object. Also, if you want to check if an object implements an Interface or Class, you can use the instanceof keyword. That's it about checking the datatype of an object in Groovy.

What does [:] mean in Groovy?

[:] creates an empty Map. The colon is there to distinguish it from [] , which creates an empty List. This groovy code: def foo = [:]

How do I define a function in Groovy?

The def keyword is used to define an untyped variable or a function in Groovy, as it is an optionally-typed language. Here, firstName will be a String, and listOfCountries will be an ArrayList. Here, multiply can return any type of object, depending on the parameters we pass to it.

How do I use variables in Groovy?

Variables in Groovy can be defined in two ways − using the native syntax for the data type or the next is by using the def keyword. For variable definitions it is mandatory to either provide a type name explicitly or to use "def" in replacement. This is required by the Groovy parser.


1 Answers

Groovy makes closures a first-class citizen. Each closure extends abstract class groovy.lang.Closure<V> and in case of undefined argument type you can use instanceof to check if parameter that was passed to a method is a closure. Something like that:

def closure = {
    println "Hello!"
}

def foo(p) {
    if (p instanceof Closure) {
        p()
    }
}

foo(closure)

Running this script generates output:

Hello!

Using concrete parameter type

Groovy allows you (and it's worth doing actually) to define a type of a method parameter. Instead of checking if p was a closure, you can require that caller passes a closure. Consider following example:

def closure = {
    println "Hello!"
}

def foo2(Closure cl) {
    cl()
}

foo2(closure)
foo2("I'm not a closure")

First call will do what closure does (prints "Hello!"), but second call will throw an exception:

Hello!
Caught: groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
    at test.run(test.groovy:18)

It's always a good practice to make your code type-safe, so you don't have to worry if a value passed as a parameter is a type you expect.

like image 131
Szymon Stepniak Avatar answered Sep 27 '22 22:09

Szymon Stepniak