Wednesday, August 29, 2012

Processing *.csv file in lift

Lift dispatch uses a Req to match a request with a response, so if you want to process the request send to the path /foo/bar.html, you can have the request:

case Req("foo" :: "bar" ::  _, "html", GetRequest)       => returnTheResponse()

Now, it would seems normal, if you want to return a csv file (request /foo/bar.csv), you would do something like this:

case Req("foo" :: "bar" ::  _, "csv", GetRequest)       => returnTheCSVResponse()

I've banged my head a long time and went into the source to find out why my request was never processed. I finally found help in this Thread , lift only parse a set of suffix, and csv is not part of it. To add it, one just need to add in boot:

LiftRules.explicitlyParsedSuffixes += "csv"

Monday, August 27, 2012

Map#getOrElseUpdate

When manipulating data in a map, I often have to use this idiom, in java

Map map = new Map<>();
Value v = map.get(key);
if(v == null) {
  v = new DefaultValue();
  map.put(key, v)

}
// do something with v

In scala, I found this really nice function on the mutable.Map: getOrElseUpdate. The implementation is located on the MapLike trait and is pretty straightforward:

/** If given key is already in this map, returns associated value.
   *
   *  Otherwise, computes value from given expression `op`, stores with key
   *  in map and returns that value.
   *  @param  key the key to test
   *  @param  op  the computation yielding the value to associate with `key`, if
   *              `key` is previously unbound.
   *  @return     the value associated with key (either previously or as a result
   *              of executing the method).
   */
  def getOrElseUpdate(key: A, op: => B): B =
    get(key) match {
      case Some(v) => v
      case None => val d = op; this(key) = d; d
    }

With this function, the previous code just become:

Value v = map.getOrElseUpdate(key, new DefaultValue())

Thursday, August 23, 2012

Option

When I started working with scala, I always had trouble writing clean code with Option until someone told me Option was just a list of 0 or 1 element.