views:

548

answers:

3

I want to create a class that takes string array as a constructor argument and has command line option values as members vals. Something like below, but I don't understand how the Bistate works.

import scalax.data._
import scalax.io.CommandLineParser

class TestCLI(arguments: Array[String]) extends CommandLineParser {
    private val opt1Option = new Flag("p", "print") with AllowAll
    private val opt2Option = new Flag("o", "out") with AllowAll
    private val strOption = new StringOption("v", "value") with AllowAll
    private val result = parse(arguments)
    // true or false
    val opt1 = result(opt1Option)
    val opt2 = result(opt2Option)
    val str = result(strOption)
}
+2  A: 

I'm not personally familiar with Scalax or Bistate in particular, but just looking at the scaladocs, it looks like a left-right disjunction. Scala's main library has a monad very much like this (Either), so I'm surprised that they didn't just use the standard one.

In essence, Bistate and Either are a bit like Option, except their "None-equivalent" can contain a value. For example, if I were writing code using Either, I might do something like this:

def div(a: Int, b: Int) = if (b != 0) Left(a / b) else Right("Divide by zero")

div(4, 2) match {
  case Left(x) => println("Result: " + x)
  case Right(e) => Println("Error: " + e)
}

This would print "Result: 2". In this case, we're using Either to simulate an exception. We return an instance of Left which contains the value we want, unless that value cannot be computed for some reason, in which case we return an error message wrapped up inside an instance of Right.

Daniel Spiewak
A: 

So if I want to assign to variable boolean value of whether flag is found I have to do like below?

val opt1 = result(opt1Option) match {
    case Positive(_) => true
    case Negative(_) => false
}

Isn't there a way to write this common case with less code than that?

JtR
+2  A: 

Here are shorter alternatives to that pattern matching to get a boolean:

val opt1 = result(opt1Option).isInstanceOf[Positive[_]]
val opt2 = result(opt2Option).posValue.isDefined

The second one is probably better. The field posValue is an Option (there's negValue as well). The method isDefined from Option tells you whether it is a Some(x) or None.

Germán