view raw
pferrel pferrel - 9 months ago 59
Scala Question

Scala how to use defaults without redefining them

I have a function defined as:

def par(min: Int = -1, exact: Int = -1, auto: Boolean = false) = {
require(min > 0 || exact > 0 || auto, "Invalid argument")
OpPar(drm, minSplits = min, exactSplits = exact)

In another function that uses this I pass in Options for the
params. I would like to allow
to use it's own defaults but don't see how to do that in Scala (without ugly logic) so I have to redefine, in effect, the defaults like this.

min = minPar.getOrElse(-1),// if par changes this may the be wrong default
exact = exactPar.getOrElse(-1),// if par changes this may the be wrong default
auto = autoPar.getOrElse(true))

If the defaults ever change this will pass the wrong defaults to
. Using complicated logic I can decide which version of
to call based on which
params are
but this is pretty ugly and would have to be written differently for every function with default params. This situation occurs with virtually every Scala lib out there. If they change the defaults and I don't notice it, my code will break.

The example above illustrates the problem but I'm looking for a Scala idiom that would cover every case where a function has defaults that could change. I want to write code that is independent of default param changes in lib functions.


So, as I understand it, you have three Options that you need to unpack and send as passed parameters, except if any option is None then the invoked method should use its own default value for the missing parameter.

It seems to me your only choice is brute force.

(minPar, exactPar, autoPar) match {
  case (Some(m),Some(e),Some(a)) => par(min=m, exact=e, auto=a)
  case (Some(m),Some(e),None)    => par(min=m, exact=e        )
  case (Some(m),None,   Some(a)) => par(min=m,          auto=a)
  case (Some(m),None,   None)    => par(min=m                 )
  case (None,   Some(e),Some(a)) => par(       exact=e, auto=a)
  case (None,   Some(e),None)    => par(       exact=e        )
  case (None,   None,   Some(a)) => par(                auto=a)
  case (None,   None,   None)    => par()

With 2 parameters it's easy. With 3 it's manageable. After that .... painful.