Scala Tutorial (Part II)

This is a continuation to a short Scala tutorial and Scala+Play Development Guide.

During the development of a project using Typesafe Stack (Scala + Akka + Play!), I learnt quite a few things about Scala and the Play framework.

Switch case statements

You can do switch statements pattern matching. A simple switch case statement looks like this:

n match {
    case 0 => println("Zero")
    case 1 => println("One")
    case n => println("It is " + n)
}

What is sealed trait

Use sealed trait as enums

sealed trait Answer
case object Yes extends Answer
case object No extends Answer

Add a folder to classpath (for reading files). Don’t have to put in src.

In Eclipse, right click, Build Path > Use As Source Folder

Folder will be in classpath. Access using

Read a resource file in Scala Play! 2

Let’s say you have a text file call myfile.txt. You should put in /public of your Play! project.

You can read the file with the following code:

val is = Application.getClass().getResourceAsStream("/public/myfile.txt")    
val src = scala.io.Source.Source.fromInputStream(is)
val iter = src.getLine
for (s <- iter)
    println(s)

Accessing Global Object

If you have an object that is initiated once when the app starts, you can put it in the Global object.

However, Global object is by default in a default package, and because it is in default package, it cannot be referenced/accessed by other packages.

The workaround is to move your Global object into a specific package, and change the application.conf file to

global= my.packaged.Global

Initializing a class

There is differences between

class Person(name:String)

and

class Person(val name:String)

In the later (with val in the constructor), you can access person.name. For former does not. Very subtle difference until when I create my first class.

Unit Testing with Specs

Write your unit tests with specs2.

To run just 1 test:

sbt test-only test.MySpec

java.lang.OutOfMemoryError: PermGen space

When sbt run, sometimes you would run into the error

java.lang.OutOfMemoryError: PermGen space

To solve, you can

brew info sbt

to look for a clue. Changing to 512M helps.

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=512M"

As much as you could googled, some solutions do not work.

Split 1 line of code into multiple lines

Something so simple does not work as you normally do in Java. For example, this would not compile:

val s = "a"
    + "b"

This is because + is a method, and it needs to be on the same line as the member calling the method (that is “a”).

Instead, this will work:

val s = "a" +
    "b"

Or you can use brackets..

val s = ("a"
    + "b")

The same goes for calling methods with dot notation. This will not work:

myClass.someMethod
    .anotherMethod

This will work:

myClass.someMethod.
    anotherMethod

Play! asText is tricky

request.body.asText is tricky. It could be None even when there is something.

Let’s same you POST some data, and you didn’t specify Content-Type: application/x-www-form-urlencoded.

Firstly, request.body.asFormUrlEncoded will be None. Okay, I understand that is because Play! is strict with missing content-type.

However, request.body.asText will be None too!

A simple HTTP POST

Dispatch is the most popular HTTP library for Scala. However, to me, it is difficult to understand, cryptic, and with poor documentation.

It took me a while to find a basic use, without using those crazy operators:

val req = url("http://my.server.com/").POST.
  setBody("yeah").
  addQueryParameter("foo", "true").
  addHeader("Content-type", "application/json")

Then gets back a response in blocking way.

val response = Http(req)()
val body = response.getResponseBody

HTTP should be that simple, and readable.

Comments