Rod
Rod

Reputation: 137

Groovy closure short-form method call doesn't work when bound via delegate?

I've created a code sample that shows the issue I'm having:

class BindingExample {

    public static void main(String[] args) {

        Closure closure1 = {
            printit.call("Hello from closure 1")
        }

        Closure closure2 = {
            printit("Hello from closure 2")
        }

        Closure printit = { s ->
            println("printing: "+s)
        }

        Binding binding = new Binding()
        binding.setVariable("printit", printit)

        closure1.delegate = binding
        closure2.delegate = binding

        closure1()  //This works fine
        closure2()  //This does not.  

        //Why does .call() work and () alone not?  Most documentation says they're the same.
    }

}

Printit is a Closure, which the documentation indicates implements doCall and therefore is callable in short form via ().

However, when this closure is made available via binding to a delegate, only the long-form version of the call is permitted. The output is:

printing: Hello from closure 1
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: groovy.lang.Binding.printit() is applicable for argument types: (java.lang.String) values: [Hello from closure 2]

Can someone explain why this is the case? If possible, I'd like to also see how to make it so the short-form version works. I was able to make it work by defining printit as a proper static method (not a closure), but that won't work for my case because I actually need printit to be given some data available only inside of the method scope (not included in the example since my question relates to the binding itself).

Upvotes: 5

Views: 396

Answers (1)

billjamesdev
billjamesdev

Reputation: 14640

As to WHY this is the case, I can't give a definite answer, unfortunately. There's some talk about implicit-"this" annotation, etc. It seems like it should work, but that there's some vagueness about what should be tried first (this-scope or delegate).

That the issue exists, currently, seems correct. I've found the following other resources that agree, with some discussion without resolution about why.

Nabble discussion about the issue: http://groovy.329449.n5.nabble.com/Binding-Closure-property-not-called-as-method-td5562137.html

JIRA ticket resulting: https://issues.apache.org/jira/browse/GROOVY-5367

Upvotes: 2

Related Questions