Details
-
Type:
Improvement
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.8-beta-1
-
Component/s: None
-
Labels:None
-
Number of attachments :
Description
This issue proposes an alternative way to meet requirement of GROOVY-3295 without the downsides discussed in that issue.
Groovy's Closure can be "coerced" into a java.util.concurrent.Callable but if we implemented that interface directly Groovy's method selection algorithm would find two methods in the example below with equal weighting:
// if Closure implemented Callable directly import java.util.concurrent.Callable Closure x = { -> println 'foo' } def a(Runnable r) { print 'runnable says '; r.run() } def a(Callable c) { print 'callable says '; c.call() } a(x) // => groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method...
The proposal is to create a special interface:
package groovy.lang public interface GroovyCallable extends Callable { }
and have Closure implement that.
This interface would NOT typically be used in any user code, instead it just causes Callable to not be a direct interface for Closure and hence Runnable would be given preference over Callable in method selection yet Closure would still implement both Runnable and Callable for the purposes of Java integration. For APIs with both Runnable and Callable methods (like above), Runnable gets preference but you can still get the Callable method through casting or the "as" operator. For APIs with just Callable, the cast or "as" operator usage would no longer be required.
Issue Links
- supercedes
-
GROOVY-3295
Make Closure a java.util.concurrent.Callable
-
An example of revised Closure in use: