言語に対する理解を深めることを目的として、コマンドラインプログラムを作ってみます。
Play Frameworkを触っていて、やはりScala言語自体に対する理解が足りなすぎることに直面した、 というのが実際のところです。
入門書について
Scalaの書籍はあまり多くないですが、今だとおそらく以下の本をまず読む人が多いと思います。
説明にあるとおりWeb版なら無料で、Kindleでも100円という安さです。
値段を考えればあまり文句も言えないのですが、タイプミスや誤りが結構あります…
入門書のようなタイプのものは、このあたりは一層気を使って欲しいところですね。
とにかく、これを一回通読したあとで、プログラムの作成に臨んでいます。
環境作成
activatorでもよかったのですが、構成についても理解が必要だと思いましたので、 sbtenvを使用します。
インストールは大抵の*envとほとんど同じです。
$ git clone git://github.com/mazgi/sbtenv.git ~/.sbtenv $ echo 'export PATH="${HOME}/.sbtenv/bin:${PATH}"' >> ~/.bashrc $ echo 'eval "$(sbtenv init -)"' >> ~/.bashrc
今回作成の最終目標にしているのは、Webページのクローリングを行うものです。
全体像はある程度考えていますが、やはり一歩ずつですね。
まずはディレクトリ構成を準備します。
$ mkdir crawler-scala ; cd $_ $ mkdir lib $ mkdir -p src/main/scala
Webページの取得
Dispatchというライブラリがあるようですが、どうも使用方法が判然としないので、 ひとまずApache HttpClientを使用します。
各種ライブラリについては、
ライブラリ依存性は二つの方法で加えることができる:
lib ディレクトリに jar ファイルを入れることでできるアンマネージ依存性(unmanaged dependencies)
ビルド定義に設定され、リポジトリから自動でダウンロードされるマネージ依存性(managed dependencies)
ということで、libディレクトリにjarを置く方法もあるようですが、 自動でダウンロードする方を使用してみます。
具体的な依存関係の設定は以下のようになりました。
build.sbt
libraryDependencies ++= Seq( "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0", "org.apache.httpcomponents" % "httpclient" % "4.5.1" )
この依存ライブラリの記述はsbtのドキュメント に詳しいことが書いてありますが。
とりあえず今回のものに関しては、’scala-logging’の’%%’は、 パッケージの名称に使用するScalaのバージョン名がつくようになります。 なので、Javaのパッケージであるhttpclientに対しても同じ記述をすると、見つからずエラーとなります。
そして、コマンドの引数にURLを設定すると、ページの内容を取得して表示するという 簡単なプログラムは以下のようになりました。
main/scala/GetPage.scala
import org.apache.http._ import org.apache.http.impl.client.HttpClients import org.apache.http.client.methods.HttpGet import org.apache.http.util.EntityUtils object GetPage { def main(args: Array[String]): Unit = { val url = args(0) try { println(this.get(url)) } catch { case e: Exception => println(e.getMessage()) sys.exit(1) } } def get(url: String): String = { val httpclient = HttpClients.createDefault() val request = new HttpGet(url) val response = httpclient.execute(request) val result = EntityUtils.toString(response.getEntity(), "UTF-8") httpclient.close result } }
Scalaらしいところはまるで無いような感じになりました。
sbtプロジェクトを実行する際、通常は’sbt run’で実行できますが、 引数がある場合は、以下のようにクォートしないと正常に認識できません。
$ sbt 'run http://www.yahoo.co.jp/' ... </html> <!-- p10.f8.top.ssk.yahoo.co.jp Wed Sep 23 23:26:10 JST 2015 --> [success] Total time: 1 s, completed Sep 23, 2015 11:26:11 PM $