Friday, August 14, 2015

Today I learned... why Scala usually doesn't use null

We Scala developers use the Option monad because it's so much better to assign None to something instead of null -- it's much safer and more explicit.

And we never have to see another NullPointerException!

Fatal exception:
None.get
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:313)
at scala.None$.get(Option.scala:311)

Now we just have to worry about not trying to call get on an Option that's None.
This is why many people in the Scala community recommend against ever using Option.get.

It's Scala's version of the NullPointerException. But it can be avoided if we use methods like map, filter, fold, foreach, getOrElse, etc., on an Option monad... Or in the Java-style, if we really have to use get, to check if it's empty first.

But sometimes you might want it to throw an exception because it means an assumption has been violated.

Sunday, August 9, 2015

Today I learned... A limitation of singletons in Scala

Singletons in Scala are pretty nice -- you can have the basic goodness of a Java singleton, but with none of the scaffolding. The static keyword is not available in Scala, so singletons are useful anytime you want a static type of behavior, but Scala singletons can extend abstract classes or traits, can be passed in, mocked, etc.

The limitation comes when you are doing unit testing and want to run multiple unit tests completely independently of each other. If your singleton has any sort of state associated with it -- not just a var or a mutable object in a val, but also something as innocuous as the current timestamp at initialization saved as a val, etc. -- then there is no way, with the possible exception of reflection, of resetting that singleton's state in-between unit tests.

These particular unit tests I'm writing are actually functional system tests -- I'm basically calling my main method with different command-line parameters once in each unit test. And since in the JVM world I can't just do something magical like shutdown and reload an AppDomain (I miss this concept from .NET), I'm stuck with state getting persisted between what are supposed to be multiple program runs, because they're all in the same JVM (of course, same as the unit test's JVM, because I'm calling them through the JVM and not through the command-line, so I can make sure they don't throw exceptions, verify side effects if desired, and so on). And the main culprit is the singleton object.

I wrote a trait that can be used to solve this problem, but unfortunately, it required refactoring all my usages of any singletons that had state, so instead of singleton.method(), it became singleton.instance.method(). Find/replace all solved this problem without any trouble for me.

The trait manages the singleton, and also requires anything extending it to have a reset method. I call the reset method for all stateful singletons in the finally block of my main method.

trait ResettableSingleton[T] {
  protected var instanceMaybe: Option[T] = None

  def isInstantiated: Boolean = instanceMaybe.nonEmpty

  /**    * Singleton instance    *    * @return Object of the class    */  def instance: T = {
    instanceMaybe synchronized {
      if (instanceMaybe.isEmpty) {
        instanceMaybe = Option(instantiate)
      }
      instanceMaybe.get
    }
  }

  /**    * Some might prefer shorter syntax, so this is just an alias for "instance"    *    * @return Instance    */  def get: T = instance

  /**    * Create an instance of the class    * This is abstract because there's no guarantee that every class has, e.g., a parameterless constructor.    *    * @return Object of the class    */  protected def instantiate: T
  /**    * Resets the singleton instance. Intended to be used if performing multiple test runs without restarting the JVM.    */  def reset(): Unit = {
    instanceMaybe = None
  }
}

Example usage:

// Take the original singleton, turn it into a class, and make the default constructor private.
class Blah private() {
  // ... Original singleton body goes here, and remains unchanged
}
/** * Resettable singleton of Blah */object Blah extends ResettableSingleton[Blah] {
/** * Create an instance of the class * @return Object of the class */ override def instantiate: Blah = {
new Blah
}
}

So I lose the syntactic sugar, but now my unit tests work. Hey, it could be worse... I could be writing Java.

Today I learned... Data-driven unit testing in Scala

I've done data-driven unit tests in C# before, but recently I learned how to do them in Scala, and it's very easy and clean.

An example unit test, using WordSpec, which follows a BDD-style syntax, is below:

"Multiplying two integers" when {
  "one is negative" should {
    "have a negative result" in {
      val positive = scala.util.Random.nextInt(10000)
      val negative = -1 * scala.util.Random.nextInt(10000)
      val result = positive * negative
      assert(result < 0, s"positive * negative should be negative, but is ${result}!")
    }
  }
}

Unit test methods can be created on-the-fly at runtime, and therefore you can take any data source and turn it into a set of unit tests. Here is an example using WordSpec, which is one of the several flavors of writing unit tests in Scala.

(1 to 100).foreach(testCaseNumber => {
  s"Test scenario $testCaseNumber" when {
    "doing something" should {
      "return success" in {
        doSomethingWithData(getDataForTest(testCaseNumber))
      }
    }
  }
}

When you run all unit tests in your class, ScalaTest will show each of these 100 data as a separate test case with separate pass/fails.

It's really slick, and if you have some common test that you want to run over and over with some slight modification that can be controlled based on some parameter, I recommend you give it a try!

Monday, August 3, 2015

Today I learned... tuple assignment in Scala


// This works
var 
(x, y) = try {
  (00)
}
// This doesn't work... would be nice if it did!
var 
x: Int = 0
var y: Int = 0
(x, y) = try {
  (00)
}