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:[email protected]]
Sent: Monday, April 18, 2016 1:50 PM
To: [email protected]
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.