Saturday, April 5, 2014

Subcut with GlobalSettings and Filters in the Play Framework

Quick post on an issue with Filters when using the Subcut template from activator.  If you use the Subcut template from TypeSafe Activator, and decide you want to use Filters on your Global object, you will likely run into this issue:

java.lang.ClassCastException: Global cannot be cast to play.GlobalSettings

or you will see that you can't call super.doFilter(next) as suggested in the documentation.

This is because there are two GlobalSettings classes in Play, one which is a Java class, and the other that is the Scala trait.  In most scala applications you will be extending a Scala trait. The Subcut template uses the Java class, and that's because the Subcut template relies on your Global being an instance, rather than a companion object, and the Scala GlobalSettings trait only works on an object, not an instance.

You can fix this problem by extending from both of these classes:

class Global extends GlobalSettings with play.api.GlobalSettings {

  override def doFilter(next: EssentialAction): EssentialAction = {
    Filters(super.doFilter(next), LoggingFilter)
  }

Thank goodness for traits!

Thursday, April 3, 2014

Raising Option[T] to Try[T] - Handling error situations with aplomb

I've started using this pattern for dealing with situation where functions I'm working with may return an Option[T] for a given query, but the contextual meaning of returning None is really an error case. A good example of this is looking up an Item in a database by it's ID based on a shopping cart. If the application receives an item ID during a shopping cart process of an item that doesn't exist in the DB, then returning None on the DAO access is fine, but the upshot is an error condition. The application has received bad data somewhere along the way, and this should be manifested as an Exception state, which I'm choosing to encapsulate in a Try[T] so I can pass it cleanly up the stack rather than violating SOLID by throwing an exception, which I know is a subject of some debate.

To help with this, I wrote a simple wrapper class that I've called MonadHelper thusly:

object MonadUtil {
  implicit def option2wrapper[T](original: Option[T]) = new OptionWrapper(original)

  class OptionWrapper[T](original: Option[T]) {
    def asTry(throwableOnNone: Throwable) = original match {
      case None => Failure(throwableOnNone)
      case Some(v) => Success(v)
    }
  }
}

This allows one to construct a for comprehension elevating None returns to an error state somewhat gracefully like this slightly contrived example:

case class CartItemComposite(account: Tables.AccountRow, item: Item)

trait AccountDAO {
  def findById(userId: Long): Option[Tables.AccountRow]
}
trait ItemDAO {
  def findById(itemId: Long): Option[Item]
}

def findShoppingCartItem(itemId: Long, userId: Long)(userDAO: AccountDAO, itemDAO: ItemDAO): Try[CartItemComposite] = {
  for {
    user <- userDAO.findById(userId).asTry(new Throwable("Failed to find user for id " + userId))
    item <- itemDAO.findById(itemId).asTry(new Throwable("Failed to find item for id " + itemId))
  } yield CartItemComposite(user, item)
}


But you get the idea. You can check a set of conditions for validity, giving appropriate error feedback at each step along the way instead of losing the error meaning as you would with simple Option[T] monads in a way that looks less than insane.

Don't know if this is a great pattern yet, but, I'm giving it a whirl!

Wednesday, November 6, 2013

SimpleDateFormat sillyness

Ran into an amazingly dumb bug yesterday. I would say that this is clearly a bug in the behavior of SimpleDateFormat in Java. Why is it that when I give it a date that looks valid, and a format string that's not right, and in fact contains invalid numbers, it will go ahead and parse my date string producing a ridiculous result. But not so ridiculous it's obvious, or in fact, just throws an Exception, which for my money would be the desired outcome.

So this is the scenario. Parsing a date like this:

val dateStr = "2013-02-04 05:35:24.693 GMT"

with the date parsing string:

val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss.SSS z")

If you're paying very close attention, you will see the problem here; the month component is repeated. This yields the following date in the resulting Date object: "Tue Nov 03 21:00:24 PST 2015"

This result is clearly very different than what was sent in. I see two problems here. The date string contained two references to the same field. I can see where sometimes this might be useful, but honestly, I feel like you should have to set a flag or something for this to be silently ignored. In most cases having a reference to the same part of a date within a format string seems like a warning flag at least. The second problem is that the erroneous value for month that was give is beyond the scope of a calendar year. You can't have 35 months in a year. In my opinion this should have thrown an exception. I understand that potentially in some calendar system somewhere on this earth there maybe more than 35 'months' in a year or something, but this is very unexpected behavior, way outside of what I would considered normal.

In short, if you have a date string that is being parsed and coming out the other end with a very strange unexpected and wrong result, there's a good chance the format string is off, and probably only very slightly and in a way that's hard to spot without a very very careful eye.

Monday, June 10, 2013

On folding, reducing and mapping

I haven't updated in a while, but it's time to get back into doing this blog.

Today I want to do a brief little thing on folding, reducing and mapping. In the past, I've found myself doing things like this when building a SQL query:
val k = Map("name" -> "John", "address" -> "123 Main St", "city" -> "Los Angeles")

(k.foldLeft("")((a,b) => a + " and " + b._1 + " = ?")).drop(6)

Which on the face of it doesn't seem so bad, might have done something not that disimilar using a for loop in Java.  The thing about this is that it's actually kind of stupid.  There is a more idiomatic way to do this.  When you think about it, the initial operation is actually a matter of mapping the input list to a set of string, and then joining those strings with the and clause.  In Scala, the reduce operation essentially does what join does in the new Java, or other languages, but with any list.  When we think about it this way, we can therefore do this:
val k = Map("name" -> "John", "address" -> "123 Main St", "city" -> "Los Angeles")

k.map(x = > x._1 + " = ?").reduce(_+" and "+_)

or:

k.map(x = > x._1 + " = ?").mkString(" and ")

Ultimately ending up as something like:
val query: PreparedStatement = buildStatement(k.map(x = > x._1 + " = ?").mkString(" and "))
k.zipWithIndex.foreach(x => query.setObject(x._1, x._2))

Much cleaner, and more idiomatic.  Some might say this is obvious, but, it wasn't obvious to me immediately, and so I'm gonna guess it's not to others either!

Thursday, January 3, 2013

Database Record Updates with Slick in Scala (and Play)

This is a simple operation that I found absolutely zero reference to in the documentation or the tutorials or the slides.  Eventually after digging through old mailing lists, I came across the solution:

        
(for { m <- MessageQ if m.id === oldMessage.id } yield(m))
  .mutate(r=>(r.row = newMessage))(session)

This is for a simple message class and a function that takes two arguments: oldMessage and newMessage.  The frustrating thing is that this is inconsistent with the simple formula for a single column update:
MessageQ.filter(_.id === 1234L).map(_.subject)
  .update("A new subject")(session)

When you try to apply this thinking to an update, you end up at a dead end.  The mutate operator is also used for deletion too:
MessageQ.filter(_.id === 1234L)
  .mutate(_.delete())(session)

Note that you can typically leave out the session argument as it's declared implicit within the appropriate scope. I'm also switching between syntax alternates because for some reason, either my IDE or the compiler gets grumpy when I try to use the filter() style rather than the list comprehension style in certain contexts. I still have to figure that out.

I'd like to write a longer post later at some point, but this at least covers the highlights.

Monday, December 17, 2012

Collect Chains for Creation - Sublime or Stupid?


I'm working on a piece of code to deserialize Facebook messages, and I'm looking at the mess I wrote to do this, and it occurred to me that I could do it as a progressive collect chain.  Each time we know something new, we collect on it, or pass-thru if it's a false condition.

def makeNewMessage(id: Long)(json: JsValue)(facebookClient: FacebookClient)(session: scala.slick.session.Session): Option[Message] = {
  (((json \ "message").asOpt[String], (json \ "created_time").asOpt[String], (json \ "id").asOpt[String]) match {
    case ((Some(message), Some(createdTime), Some(fbId))) => {
      Some((userId: Long) => (likes: Int) => Message(
        id = id,
        subject = None,
        systemUserId = Some(userId),
        message = Some(message),
        createdTimestamp = Some(new sql.Date(facebookDateParser.parse(createdTime).getTime)),
        facebookId = Some(fbId),
        upVotes = Some(likes)
      ))
    }
  }).collect({ case f => {
    scaffoldFacebookUser(json)(facebookClient)(session) match {
      case Right(scaffoldedId: Int) => f(scaffoldedId)
    }
  }}).collect({ case f => f(((json \ "likes").asOpt[Int], (json \\ "likes").size) match {
    case (Some(likes), 0) => likes
    case (_, likes) => likes
  })})
}


The result of the first piece is a 2-ary function that may get populated with a userId and a like count.  Once we figure out if we can build a user, we populate that, then we figure out the like count.  If at any point the chain fails, it just returns None.

This all feels very imperative to me, perhaps I'm just tired, and it will come to me later. I swear I remember better ways of doing this using unapply magic, but I can't seem to figure it out, so this is where I'm going right now!

Wednesday, October 24, 2012

Head shaking moments - an ongoing Saga

I think I might start to keep track of examples of bad code that are right out there in the public view.  Some of these examples are the language tutorials themselves even!

Today I'm gonna single out the object example in the CoffeScript guide.  In this guide we get the Animal class example:

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

This code is in violation of the Call Super code smell.  We finally get half decent classes in Javascript using CoffeeScript, and this is the first example given - one that is considered by some to be an anti-pattern.  Below I'm going to feature an attempt to refactor out this smell.

Updated Code
class Animal
  constructor: (@name) ->

  move: (meters = @distance()) ->
    alert @movingMessage()
    alert @name + " moved #{meters}m."

  movingMessage: -> "Moving..."
  distance: -> 10


class Snake extends Animal
  movingMessage: -> "Slithering..."
  distance: -> 5

class Horse extends Animal
  movingMessage: -> "Galloping..."
  distance: -> 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

Delegate methods are a much better use for an inheritance contract than methods that override a super to provide essentially the same behavior, only with different parameters. I would argue that the second version is substantially clearer as each method does precisely one thing, including the move method of Animal.