Given that Groovy already extends Java, what's the problem with providing setter overloads?
They turn out to be very useful.
The current behavior of '=' in Groovy is really pretty weird:
- Explicit calls in Groovy to setMyProperty(...) always work correctly, even when overloaded.
- If I have a Java getter that returns type X and a non-overloaded Java setter:
- If the Java setter takes type X, then Groovy's '=' will work properly.
- If the Java setter takes type Y, then Groovy's '=' will try to convert the type of the Groovy arg proved to the Java getter's return type, and possibly fail.
- If I have a Java getter that returns type X and the Java setter is overloaded to accept type X and Y:
- If the Groovy arg provided to '=' is of type X, then the Java setter called will be the one for X.
- If the Groovy arg provided to '=' is of type Y, Groovy first tries to convert it to an X (possibly failing), then calls the Java setter for type X.
This behavior is astonishing.
It is also unhelpful / unproductive.
Overloaded setters turn out to be very useful. I dont' care if it's the bean spec or not.
I want to be more productive when working with the JVM – this is why I want to program
in Groovy to begin with. Why does '=' need to force itself into the tiny box of only working
with Java beans, when java itself allows you overload setYourProperty(...) and Groovy
happily such overloads correctly now? I want that happiness to extend to the '=' operator!
Let's motivate this discussion with a concrete example from real life (my own!):
In Gradle, the 'javadoc' task is kind of lame as of 0.5.2; it does not take very many of the
bazillion arguments that the Ant Javadoc task can take.
(see: http://api.dpml.net/ant/1.6.5/org/apache/tools/ant/taskdefs/Javadoc.html#setAccess(org.apache.tools.ant.taskdefs.Javadoc.AccessType) )
I wanted to help fix that, because I actually need to use some of these parameters myself and don't like dropping down into
the much more verbose ant.javadoc(....) syntax because it does not provide many of the nice features the built-in Gradle javadoc
Currently, if I've overloaded the setter for 'overview' with one function that takes a String and another with a File, I could say either:
setOverview( new File("$srcRoot/overview.html") )
However that's rather ugly, and Gradle uses Groovy to be prettier & friendlier.
I'd like to use the '=' syntax for setter overloads just as nicely as I can use explicit setOverview(...)
Groovy lets you play fast & loose with types.
Users expect that:
- If a user has "Ant XML name/type expectations", then they're prone to provide string values to the task.
- If a user has Ant API name/type expectations", then they're prone to give the API type to the task.
So, I want everybody to succeed, by default, as they'd expect (whomever they are).
Specifically, consider two Ant javadoc properties: 'header' and 'overview'
With 'header' Ant's API wants you to give it a String (as does the XML)
With 'overview', Ant's API wants you to give it a File (but the XML wants a String, of course).
It would be nice Groovy were to be able to support either syntax for Gradle's 'javadoc' task:
header = "I want a pony!!!"
overview = "$srcRoot/overview.html" }
And also this:
header = "I want a pony!!!"
overview = new File("$srcRoot/overview.html") }
As things stand, I cannot do this in Groovy 1.5.6.
When I dug deeper into exactly how '=' works, I came away a sadder Groovy user.
I hope this motivating case is persuasive enough to show that setter overloads for '=' have
non-arcane uses, they're consistent with java support for overloaded setMyproperty(...),
and consistent with Groovy's "just do the right thing" attitude.
Is there some technical reason why it's difficult to make '=' work nicely
while explicit calls to an overloaded setMyProperty(....) is easier?
If so, could you explain it?