Skip to content

Instantly share code, notes, and snippets.

@davidallsopp
Last active March 30, 2016 13:59
Show Gist options
  • Select an option

  • Save davidallsopp/a5bb20faa7ddb7931f16 to your computer and use it in GitHub Desktop.

Select an option

Save davidallsopp/a5bb20faa7ddb7931f16 to your computer and use it in GitHub Desktop.
Handling stringly-typed configuration (e.g. config files, system properties). This is a Scala IDE worksheet - you'd package up the code differently in a real app.
import scala.language.implicitConversions
object configs {
// Options (e.g. from a config file or system properties), as key-value strings
val opts = Map("min" -> "100", "path" -> "/home/user2")
// Automatically wrap the default values in a Some
// (or can omit this and specify None to indicate lack of a default value)
implicit def wrap[A](a: A) = Some(a)
// Implicit conversion for each output type we want:
implicit def toString(s: String) = s
implicit def toInt(s: String) = s.toInt
implicit def toBoolean(s: String) = s.toBoolean
// Generic function that uses one of the implicits.
// Every setting must be present, or have a default.
def get[A](key: String, default: Option[A] = None)(implicit convert: String => A): A =
getOption(key, default).getOrElse(throw new Exception(key))
//> get: [A](key: String, default: Option[A])(implicit convert: String => A)A
// Allow missing (optional) config settings
def getOption[A](key: String, default: Option[A] = None)(implicit convert: String => A): Option[A] =
opts.get(key).map(convert).orElse(default)
// now extract the desired options, with or without default values.
// Need to declare the types so we know which implicit to use.
val min: Int = get("min", 10) //> min : Int = 100
val max: Int = get("max", 10) //> max : Int = 10
//val max2: Int = get("max") // Exception - missing value and no default
val path: String = get("path") //> path : String = /home/user2
// or can specify lack of default explicitly:
val path2: String = get("path", None) //> path2 : String = /home/user2
//val bad: Boolean = get("bad", None) // Exception - missing value and no default
// Optional config settings
val path3: Option[String] = getOption("path") //> path3 : Option[String] = Some(/home/user2)
val nopath: Option[String] = getOption("nopath")//> nopath : Option[String] = None
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment