3. Accessing config values

Config extends ListMap, making it very easy to use. It assumed that you are familiar with Scala’s Map (and ListMap) collection classes. For clarity, the following examples have the explicit type declared on each val, which is not usually necessary in Scala.

Here’s a sample file we’ll be discussing:

a = something
b = else
easy = true
tau = 6.2832

somewhen = 1979-05-27T07:32:00Z
coronation = 1953-06-02

triangle = 3, 4, 5

actors = "\"Harry\", Daniel Radcliffe", "\"Ron\", Rupert Grint", "\"Hermione\", Emma Watson"

timeout = 60s
maxHeap = 2 GiB
maxTemp = 90°C

Simple Cases

∘ Load a string value directly. As with any Map, NoSuchElementException is thrown if the key isn’t found.

  val a: String = config("a")

∘ Load a value as an optional string. No exception comes if the key is missing.

  val aOption: Option[String] = config.get("a")

Conversions

∘ Load a value directly and convert its type. Scala’s StringLike helps a lot, working for Byte, Short, Int, Long, Float and Double too.

  val flag: Boolean = config("easy").toBoolean
  val tau: Float = config("tau").toFloat

∘ BigInteger and BigDecimal are slightly different: it’s best to convert directly from a string (avoid an intermediate Double studiously!)

  val tauD: BigDecimal = BigDecimal(config("tau"))

∘ If you want the optional version you can still convert it simply by using Scala’s map

  val optionalFlag: Option[Boolean] = config.get("easy").map(_.toBoolean)
  val optionalTau: Option[Float] = config.get("tau").map(_.toFloat)
  val optionalTauD: Option[BigDecimal] = config.get("tau").map(BigDecimal(_))

∘ Other types like dates are straightforward. Here’s how to parse a Joda DateTime

  import org.joda.time._
  import org.joda.time.format._
  val fmt1 = ISODateTimeFormat.dateTime()
  val somewhen: DateTime = fmt1.parseDateTime(config("somewhen"))
  val fmt2 = DateTimeFormat.forPattern("yyyy-MM-dd")
  val coronation: DateTime = fmt2.parseDateTime(config("coronation"))

Values with Units

∘ Values can have units. Time and memory size support are built-in; any other units can be used also. SI/IEC multiplier prefixes can also be used. Access these with the value method.

  val timeout = config.value("timeout").toDuration
  val maxHeap = config.value("maxHeap").toMemorySize
  val maxTemp = config.value("maxTemp").withUnit

The timeout has type Duration; the maxHeap has type MemorySize; the maxTemp has the more general type DimensionedValue

Lists

∘ Convert comma-separated lists via the getList method of Config. On the previous page, we saw a configuration example that had a list of three actors.

  val actors: List[String] = config.getList("actors")

Here we get

  • “Harry”, Daniel Radcliffe
  • “Ron”, Rupert Grint
  • “Hermione”, Emma Watson

Although getList always returns a list of strings, it is easy in Scala to convert the types.

  val numbers: List[Int] = config.getList("triangle").map(_.toInt)