バイトとかでScalaに触ったことはあるけど、そういえば自分で1からプロジェクト作ったことは無かったなぁと思ったので。

インストール

各々の環境に合わせて。僕はMacなんでbrew使いました。

$ brew install sbt

とりあえず実行

$ sbt console

と打てばとりあえず対話型実行環境を作ってくれますが、実行するとカレントディレクトリ以下に必要なパッケージ等を含んだディレクトリが勝手にできてくれやがりますので適当なディレクトリを作ってそこで実行するのがおすすめ。とりあえず以下では、「myfirst」というディレクトリを作成し、そこに新しいプロジェクトのソースファイル等を置いていくことにします。

build.sbtの作成

プロジェクトの名前やバージョン、他のパッケージへの依存関係を定義するために、build.sbtというファイルを作成します。
http://www.scala-sbt.org/0.13/docs/ja/Basic-Def.html 等を参考にしつつ、とりあえず最低限必要な設定だけ。

lazy val root = (project in file(".")).
  settings(
    name := "my-first-project",
    version := "0.0.1",
    scalaVersion := "2.10.5"
  )

これを先ほど作成した「myfirst」直下にbuild.sbtという名前で保存します。

ソースコードの配置

(プロジェクトのディレクトリ)/src/main/scala/ 以下にScalaのソースファイルを置くのが普通みたいです。とりあえず簡単なHello Worldを作成して、myfirst/src/main/scala/HelloWorld.scalaという名前で保存してみましょう。

object HelloWorld extends App {
  println("Hello world")
}

実行

$ sbt run

を実行すると、現在のプロジェクト内にある実行可能なクラスを実行してくれます。先程のソースファイルが正しく配置されているならば、(sbtのメッセージが出力された後に)"Hello world"という文字列が出力されるはずです。

外部ライブラリの使用

これで終わりでは面白くないので、外部ライブラリを使用したプログラムを作成してみます。
今回はscalaj-httpとjson4sを利用して、外部のウェブサイトのAPIを適当に叩いてみるプログラムを書いてみましょう。(書いた後で最近はdispatchとかいうもう少しナウい感じのhttpクライアントライブラリがあることに気付いた)

まずはbuild.sbtに以下のように依存関係を追加します。

lazy val root = (project in file(".")).
  settings(
    name := "my-first-project",
    version := "0.0.1",
    scalaVersion := "2.10.5",
    libraryDependencies ++= Seq(
      "org.scalaj" %% "scalaj-http" % "2.2.1",
      "org.json4s" %% "json4s-native" % "3.3.0"
    )
  )

利用可能なライブラリのバージョンとかについては http://mvnrepository.com/ とかで探すといいかも。

このライブラリを使用して適当にコードを書きます。

import scalaj.http._

import org.json4s._
import org.json4s.DefaultFormats
import org.json4s.native.JsonMethods._

case class Station(
  name: String,
  x: Double,
  y: Double
)

object StationAPI {
  val baseUrl = "http://geoapi.heartrails.com/api/json"
  implicit private val formats = DefaultFormats

  def getNearest(postal: String): Option[Station] = {
    val resp = Http(baseUrl).
      param("method", "getStations").
      param("postal", postal).
      asString
    if (resp.isError) {
      return None
    } else {
      val json = parse(resp.body)
      return (json \ "response" \ "station").extractOpt[Station]
    }
  }
}

json.extract[T]でT型のcase classに勝手に変換してくれるのが超便利。
HeartRails | ハートレイルズ | ザ・ウェブサービス・カンパニー というサイトのAPIを使って、郵便番号を渡すと最寄り駅の名前とその位置を返してくれるようなオブジェクトを作りました。これをsrc/main/scala/Station.scalaとかいった名前で保存しておきます。

最後にHelloWorldも少しだけ変更します。

object HelloWorld extends App {
  println("Hello world")

  val station = StationAPI.getNearest("6068301")
  station match {
    case Some(s) => println("nearest station: " + s.name)
    case _ => println("no station around there")
  }
}

実行すると、以下のように出力されるはずです。

$ sbt run
(ログがいろいろ)
Hello world
nearest station: 出町柳
(この後もログがいろいろ)

ちなみに、606-8301とは みんな大好きにぼ次朗百万遍店 の郵便番号です。

sbtプラグインのインストール

今度は、完成したプログラムをjarファイルにまとめてみましょう。
sbt自体の機能にも

$ sbt package

でjarファイルに固めてくれる機能はありますが、この機能だと依存関係にあるライブラリのファイルなどはjarに含めてくれないため、配布には不向きです。
そこで、sbt-assemblyというsbtのプラグインを利用してみましょう。

最近のバージョンから、sbtへのプラグインの追加はかなり簡単になったらしいです。
インストールはproject/assembly.sbtに以下の記述をするだけ

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1")

保存後、

$ sbt assembly

を実行するだけで、target/scala-2.10以下にmy-first-project-assembly-0.0.1.jarを作成してくれます。
実際に実行してみると……

$ java -jar target/scala-2.10/my-first-project-assembly-0.0.1.jar 
Hello world
nearest station: 出町柳

先程と同様の結果が出力されました。


これだけできれば、Scalaで適当なアプリケーションを作る際の流れは一通り捕めたのではないでしょうか。
今年はLancersScalaのコード書きまくって一儲けしてバイト辞めたいです。


Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

言わずと知れたScalaのバイブル。Scala自体の機能については一通り書いているので、とりあえず全体像を捕みたい場合にはいいと思います。

これからの「標準」を身につける HTML+CSSデザインレシピ (Web Designing Books)

これからの「標準」を身につける HTML+CSSデザインレシピ (Web Designing Books)

最近いろいろあって、とあるイベントの公式サイトの運営をさせてもらっています。Web関連はHTMLとかCSSでできること自体に関してはなんとなく知ってるけど、それを使って実際にウェブサイトを制作していく過程を学びたかったので購入した1冊。基本的なWebデザイン作業の勧め方から、Bootstrap等の使い方まで書いてます。
余談ですが、最近はScalaでクライアントサイドからサーバーサイドまで全て書くことができるらしいですね。次にウェブ関連をやる機会があれば全てScalaでやるのも面白いかも。AngularJSとかReact.jsあたりのフレームワークも対応しているライブラリがあるみたいですし。
GitHub - greencatsoft/scalajs-angular: AngularJS Binding for Scala.js
GitHub - japgolly/scalajs-react: Facebook's React on Scala.js

こちらもデザイン力を身に付けたくて購入した1冊。Webに限らず(というかWebについてはあまり想定されてない印象)、デザイン一般について学べます。少し前までサークルのイベントの関連でポスター等の情報宣伝物の制作に関わる機会が多かったので、その間にもっと勉強しておけばよかった……。