You know, I bet that could be done with an ast transformation. Using it could look like this:
@RequiredConstructorParameters(parameters = ['a']) class Foo { String a String b } On Apr 18, 2016 2:33 PM, "Winnebeck, Jason" <jason.winneb...@windstream.com> wrote: > I think Groovy is limited here to the JVM's features. It is not possible > to implement named parameters properly since you don't know the method > names (except when using an optional compiler param in Java 1.8+), so there > is not truly named parameters in Groovy. Instead, all of the named > parameters are converted into a Map. And Groovy does allow positional and > named parameters in the same call, where all of the named parameters are > collected into a single map. > > As far as I know the best solution for enforcing the named parameters is > just to check for their presence in the map manually in the function itself. > > The only place I see in Groovy where "named parameters" actually works > well is when constructing an object -- the names parameters all turn into > setter calls. It is possible to abuse this so that Groovy code would fail > when trying to set non-existant parameters, but it doesn't solve the > required parameters issue without manual code. It also has the benefit of > code completion in IDE and type checking. Specifically I am talking about: > > class FooCall { > String a > String b > > void call() { > if (!a || !b) > throw new IllegalArgumentException("a and b are required"); > println "call $a $b" > } > } > > new FooCall(a:"a", b:"b")() > > However, the code is very awkward. That's not much better than: > > REQ_PARAMS = ['a', 'b'] as Set > ALL_PARAMS = REQ_PARAMS + ['c'] as Set > > void foo(Map params) { > params = params ?: [:] > if (!params.keySet().containsAll(REQ_PARAMS)) > throw new IllegalArgumentException("Missing required parameters > ${REQ_PARAMS - params.keySet()}") > if (params.keySet() - ALL_PARAMS) > throw new IllegalArgumentException("Extra parameters ${params.keySet() > - ALL_PARAMS}") > > println "foo $params" > } > > foo(a:1, b:1, c:1) > > Jason > > -----Original Message----- > From: David M. Karr [mailto:davidmichaelk...@gmail.com] > Sent: Monday, April 18, 2016 1:50 PM > To: users@groovy.apache.org > Subject: Required named parameters in constructor? > > First of all, I'm not attempting a "Groovy vs. anything else" argument, so > put away the flamethrowers. I find myself defending Groovy when I have the > chance. > > I was, however, reading a Ruby book, as I've never looked at it before, as > I found I had to learn about Puppet, and I concluded that you can't work > effectively with robust Puppet modules without understanding Ruby. > > As a result, I found myself paying attention to to how Ruby features map > to Groovy. I'm not talking about syntax, just functional features. > > I got to the point in the Ruby book where it mentioned that you could set > particular keyword parameters (like Groovy Named Parameters) to be > required. I can't think of a "direct" way to map this to Groovy. I > suppose you could implement an "ad hoc" strategy that throws if particular > values aren't set. Is there a more concise way? > > Just as an observation, I also note that Ruby allows mixing both > "positional" and "named" parameters in the same constructor call. > > ---------------------------------------------------------------------- > This email message and any attachments are for the sole use of the > intended recipient(s). Any unauthorized review, use, disclosure or > distribution is prohibited. If you are not the intended recipient, please > contact the sender by reply email and destroy all copies of the original > message and any attachments. >