Explore JVM Libraries in a Quick sbt Session

Dear younger me, here's a quick way to try out a new third-party library in the Scala REPL without having to create a new sbt project or edit the sbt build file.

In this particular example I'm just playing around with dispatch, trying to see whether it sends the correct query parameters to httpbin.org.

Create Temp Directory

This is an optional step, but I do it because sbt creates two sub-directories: project and target, and I don't like to pollute whatever directory I'm in (usually $HOME or Desktop).

λ Desktop master: mkdir -p sbt-project
λ Desktop master: cd sbt-project/
λ sbt-project master: sbt
[info] Set current project to default-a63394 (in build file:/Users/igstan/Desktop/sbt-project/)

Set Scala Version

> set scalaVersion := "2.10.0"
[info] Defining *:scala-version
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to default-a63394 (in build file:/Users/igstan/Desktop/sbt-project/)

Add Library as Dependency

> set libraryDependencies += "net.databinder.dispatch" %% "dispatch-core" % "0.10.0"
[info] Defining *:library-dependencies
[info] The new value will be used by *:all-dependencies
[info] Reapplying settings...
[info] Set current project to default-a63394 (in build file:/Users/igstan/Desktop/sbt-project/)

Enter the REPL

> console
[info] Updating {file:/Users/igstan/Desktop/sbt-project/}default-a63394...
[info] Resolving org.slf4j#slf4j-api;1.6.2 ...
[info] Done updating.
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

Import Dependencies

scala> import dispatch._, Defaults._
import dispatch._
import Defaults._

Create a Request Builder

scala> val u = url("http://httpbin.org/get")
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
u: com.ning.http.client.RequestBuilder = com.ning.http.client.RequestBuilder@2cce6b12

Add Some Query Params

scala> u <<? Seq("a" -> "foo", "b" -> "bar")
res0: com.ning.http.client.RequestBuilder = com.ning.http.client.RequestBuilder@2cce6b12

Execute Request

scala> val r = Http(u.OK(as.String))
r: dispatch.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@7495a73e
scala> r.onComplete(println(_))

scala> Success({
  "args": {
    "a": "foo",
    "b": "bar"
  },
  "headers": {
    "Connection": "close",
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "Dispatch/0.10.0"
  },
  "url": "http://httpbin.org/get?q=foo"
})

scala>

Improvements

I've added a bash alias that saves me from creating a scratch directory every time I'd like to play with some library:

take () {
  mkdir -p $1 &&
  cd $1
}

alias sbt-playground="take '$HOME/.sbt-playground' && sbt"

Also, because the command to add a library dependency is quite long, I've created an sbt alias in $HOME/.sbtrc:

alias dep=set libraryDependencies +=

Now, all I have to type in the sbt console is this command:

> dep "net.databinder.dispatch" %% "dispatch-core" % "0.10.0"