Mark Needham

Thoughts on Software Development

Scala: Setting a default value

with 4 comments

We wanted to try and generate a build label to use for the name of the artifacts archive that gets generated each time we run the build but wanted to default it to a hard coded value if the system property representing the build label wasn’t available.

In Ruby we would be able to do something like this:

buildLabel =  ENV["GO_PIPELINE_LABEL"] || "LOCAL"

There isn’t a function in Scala that does that so we initially ended up with this:

  def buildLabel() = [{ 
    System.getenv("GO_PIPELINE_LABEL") match {
      case null => "LOCAL"
      case label => label
    }                                                                                                                                                                                                     
  }

My colleague Mushtaq suggested passing the initial value into an Option like so…

def buildLabel() = {
	Option(System.getenv("GO_PIPELINE_LABEL")).getOrElse("LOCAL")
}

…which I think is pretty neat!

I tried to see what the definition of an operator to do it the Ruby way would look like and ended up with the following:

class RichAny[A](value:A ) {                              
      def || (default:A ) = {  Option(value).getOrElse(default)  }
}
implicit def any2RichAny[A <: AnyRef](x: A) = new RichAny(x)

Which we can use like so:

def buildLabel() = {
System.getenv("GO_PIPELINE_LABEL") || "LABEL"
}

I imagine that’s probably not the idiomatic Scala way to do it so I’d be curious to know what is.

Written by Mark Needham

June 12th, 2011 at 4:03 pm

Posted in Scala

Tagged with

  • Stacy

    You’ve just implemented the null-coalescing operator, I’d recommend using the C# syntax: ??

    Scalaz has various pieces of mathematically inspired syntactic sugar.

    I’ve added so many methods to my own RichAny class that it no longer fits on a page, ‘partialMatch’ is perhaps my favourite:

    class RichAny[T](value: T) {
      def partialMatch[V](pfn: PartialFunction[T, V]): Option[V] = pfn.lift(value)
    }

    // usage:
    val (foo, bar) = (Some(123), Some(456))

    // res will be of type: Some[Int]
    val res = (foo, bar) partialMatch {
      case (Some(x), Some(y)) => x*y
    }

  • http://twitter.com/markhneedham Mark Needham

    Good point, didn’t think about that.

    Thanks for the scalaz reference, hadn’t heard of that before. We’ve got one problem where we need a very functional approach to it so those functions might come in useful there.

  • http://patforna.blogspot.com Patric Fornasier

    It will look even neater if you get rid of the parantheses and braces ;)

    def buildLabel = System.getenv(“GO_PIPELINE_LABEL”) || “LABEL”

  • Kenbot

    In Scala 2.9, you can access environment variables through sys.env, which is a Map[String,String]; map also has a getOrElse method.

    sys.env.getOrElse(“GO_PIPELINE_LABEL”, “LABEL”)