Comment utiliser scalax.io.CommandLineParser?
-
05-07-2019 - |
Question
Je souhaite créer une classe qui utilise un tableau de chaînes en tant qu'argument de constructeur et qui possède des valeurs d'option de ligne de commande en tant que membres vals. Quelque chose comme ci-dessous, mais je ne comprends pas comment fonctionne le Bistate.
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)
}
La solution
Voici des alternatives plus courtes à cette correspondance de modèle pour obtenir un booléen:
val opt1 = result(opt1Option).isInstanceOf[Positive[_]]
val opt2 = result(opt2Option).posValue.isDefined
Le second est probablement meilleur. Le champ posValue est une option (il existe également negValue ). La méthode isDefined de Option vous indique s'il s'agit d'un Some (x) ou d'un None.
Autres conseils
Je ne connais pas personnellement Scalax ou Bistate
, mais si je regarde les scaladocs, cela ressemble à une disjonction gauche-droite. La bibliothèque principale de Scala a une monade très semblable à celle-ci ( Soit
), donc je suis surpris qu'ils n'aient pas simplement utilisé la bibliothèque standard.
En substance, Bistate
et Soit
sont un peu comme Option
, sauf que leur "" Aucun
-équivalent". ; peut contenir une valeur. Par exemple, si j'écrivais du code en utilisant Soit
, je pourrais faire quelque chose comme ceci:
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)
}
Ceci imprimerait " Résultat: 2
". Dans ce cas, nous utilisons Soit
pour simuler une exception. Nous retournons une instance de Left
qui contient la valeur que nous voulons, à moins que cette valeur ne puisse être calculée pour une raison quelconque, auquel cas nous renvoyons un message d'erreur encapsulé dans une instance de Right
.
Donc si je veux assigner à une variable booléenne une valeur indiquant si un drapeau est trouvé, je dois faire comme ci-dessous?
val opt1 = result(opt1Option) match {
case Positive(_) => true
case Negative(_) => false
}
N'y a-t-il pas moyen d'écrire ce cas commun avec moins de code que cela?