Skip to content

Option types and definitions

Rogach edited this page Jan 12, 2013 · 7 revisions

Scallop supports three types of options - "standard" options (-a), property options (-Dkey=value), and trailing arguments.

Plain options

Example definition:

val apples = opt[Int]("apples", default = Some(10), validate = (0<))

Here, we defined a simple option, which can be supplied on the command line with --apples or -a, takes an integer number (which should be greater than 0), and defaults to 10 if not supplied.

Short option name is determined from long name in this case - using the first character. If there are several options, that all start with same character, only the first option will have the short option name. (you can explicitly change this behavior with short setting)

In the example, val apples contains ScallopOption[Int], and the underlying value can be accessed by ether calling .apply() or .get on it:

apples() should equal (10)
apples.get should equal (Some(10))

opt method takes the type argument, which is used to look up a ValueConverter for the arguments. Default converters are provided for all primitive types (Int, String, Double, ...) and for lists of those types (List[Int]). (you can define your own custom converter)

opt method arguments are all named and have a default value, so you can omit most of them. The arguments include:

  • short - By default, the first character of option name is used for short option name. You can override it by specifying the needed character (short = 'c').
  • descr - Description for the option. Will be printed in help message, carefully formatted to 80 characters width.
  • default - Contains an option with the default value for the option.
  • validate - A validation function of the type [A=>Boolean], where A is your option type.
  • required - Is this option required? For plain option, this setting defaults to false.
  • argName - The name of argument to this option, as it will be printed in the help message.
  • hidden - Sometimes you want to exclude the option from the help message printout (for debugging, maybe).
  • noshort - If you want to explicitly forbid any short name for this option.

Special case of plain options are the flag options. They take no arguments, and evaluate to true if option was present on the command line or to false if it was not:

val verbose = opt[Boolean]("verbose")

Option name guessing

As you can see, sometimes you need to type option name twice (in field name and in option name):

val apples = opt[Int]("apples")

To eliminate this redundancy, for plain options you can omit the option name, and Scallop will use the field name (converting camelCase to hyphen-case):

val apples = opt[Int]()
val name = opt[String]()

Property arguments

Scallop allows flexible property arguments definition:

  • -Dkey=value
  • -D key1=value1 key2=value2
  • -Dkey=value key1=value1 key2=value2

And property values can also be typed:

val properties = props[Double]('D')

Accessing properties is also easy:

properties("key") should equal (Some("value"))
propMap[String]('D') should equal (Map("key" -> "value"))

props method also has some more funny arguments:

  • descr - Description.
  • keyName - Name of the "key" part of the argument, as it will appear in the help printout (defaults to "key" - "-Dkey=value").
  • valueName - Name of the "value" part of the argument.
  • hidden - if set to true, hides the option from help printout.

Trailing arguments

Scallop supports powerful matching on the trailing arguments. The use cases can range from simple:

object Conf extends ScallopConf(List("aoeu", "asdf")) {
  val first = trailArg[String]()
  val second = trailArg[String](required = false)
}
Conf.first() should equal ("aoeu")
Conf.second.get should equal (Some("asdf"))

... to quite tricky cases:

object Conf extends ScallopConf(
       List("-Ekey1=value1", "key2=value2", "key3=value3", 
            "first", "1","2","3","second","4","5","6")) {
  val props = props[String]('E')
  val firstListName = trailArg[String]()
  val firstList = trailArg[List[Int]]()
  val secondListName = trailArg[String]()
  val secondList = trailArg[List[Double]]()
}
Conf.props("key1") should equal (Some("value1"))
Conf.firstListName() should equal ("first")
Conf.secondListName() should equal ("second")
Conf.firstList() should equal (List(1,2,3))
Conf.secondList() should equal (List[Double](4,5,6))

In this case, Scallops backtracking parser is clever enough to distinguish the boundaries of the arguments lists.

trailArg arguments are not so abundant:

  • name - the name of the option, as it will appear in summary message. Auto-generated by default.
  • required - true by default.
  • default - the value to use if user haven't supplied one.
  • descr - description of this option, used for help printout.
  • hidden - if set to true, hides the option from help printout.

'Toggle' options

Basically, it is a glorified flag option - it can be explicitly set to 'on' of 'off', or left with it's default value.

object Conf extends ScallopConf(List("--noverbose")) {
  val verbose = toggle("verbose")
}
Conf.verbose.get should equal (Some(true))
Conf.verbose.isSupplied should equal (true)

toggle arguments allow you to fine-tune the behavior:

  • name - the name of the option, used to generate the possible option names.
  • default - default value - either Some(true) or Some(false). None by default.
  • short - short name for "positive" version of an option. Defaults to first character of a name.
  • noshort - if set to true, no short versions of the option will be created.
  • prefix - Prefix to option name, which is used to generate "negative" version of an option. Defaults to "no" ("verbose" -> "noverbose").
  • descrYes - description for "positive" version of this option.
  • descrNo - description for "negative" version of this option.
  • hidden - if set to true, hides the option from help printout.

Verification

Scallop should know your full option setup before it can start to parse options. So if you try to extract values from ScallopOption before initialization ended (or before explicitly calling verify method), you'll get an error, as shown here:

object Conf extends ScallopConf(arguments) {
  val apples = opt[Int]("apples")
  println(apples.get) // <- don't do this
  val name = trailArg[String]()
}

Instead of this, you can prefix all extraction operations with lazy keyword. Also, even better, you can use lazy operations on ScallopOption.