groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Winnebeck, Jason" <Jason.Winneb...@windstream.com>
Subject RE: Required named parameters in constructor?
Date Mon, 18 Apr 2016 18:33:14 GMT
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:davidmichaelkarr@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.
Mime
View raw message