Scala Pattern matching makes code more readable
19 Jul 2014Recently I was working on a scala project that required parsing text to create case classes that can be treated as commands that get passed to other subsystems. The following string commands had to be mapped into cases classes.
SET foo bar
GET foo
BEGIN
COMMIT
ROLLBACK
END
Following are the case classes the commands needed to be mapped to
trait Command
case class SetCommand(key: String, value: String) extends Command
case class GetCommand(key: String) extends Command
case class BeginCommand() extends Command
case class CommitCommand() extends Command
case class RollbackCommand() extends Command
case class EndCommand() extends Command
Initially I implemented the parsing logic using if else
construct and this is what the code looked like
def parse(rawCommand: String): Option[Command] = {
val pieces: Seq[String] = rawCommand.trim.split(" ")
if (pieces.size == 1) {
if (pieces(0) == "BEGIN") Some(BeginCommand())
if (pieces(0) == "COMMIT") Some(CommitCommand())
if (pieces(0) == "ROLLBACK") Some(RollbackCommand())
if (pieces(0) == "END") Some(EndCommand())
else None
} else if (pieces.size == 3 && pieces(0) == "SET") {
Some(SetCommand(pieces(1), pieces(2)))
} else if (pieces.size == 2 && pieces(0) == "GET") {
Some(GetCommand(pieces(1)))
} else {
None
}
}
After reimplementing the parsing logic using pattern matching the code is more compact and easier to understand (IMHO)
def parse(rawCommand: String): Option[Command] =
rawCommand.trim.split(" ") match {
case Seq("BEGIN") => Some(BeginCommand())
case Seq("COMMIT") => Some(CommitCommand())
case Seq("ROLLBACK") => Some(RollbackCommand())
case Seq("END") => Some(EndCommand())
case Seq("SET", key, value) => Some(SetCommand(key, value))
case Seq("GET", key) => Some(GetCommand(key))
case _ => None
}
Pattern matching FTW!