Search code examples
functiongroovyparameterstypechecking

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?


Solution

  • 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.