言語に対する理解を深めることを目的として、コマンドラインプログラムを作ってみます。

Play Frameworkを触っていて、やはりScala言語自体に対する理解が足りなすぎることに直面した、 というのが実際のところです。

入門書について

Scalaの書籍はあまり多くないですが、今だとおそらく以下の本をまず読む人が多いと思います。

Guide to ScalaーScalaプログラミング入門

説明にあるとおりWeb版なら無料で、Kindleでも100円という安さです。

値段を考えればあまり文句も言えないのですが、タイプミスや誤りが結構あります…

入門書のようなタイプのものは、このあたりは一層気を使って欲しいところですね。

とにかく、これを一回通読したあとで、プログラムの作成に臨んでいます。

環境作成

activatorでもよかったのですが、構成についても理解が必要だと思いましたので、 sbtenvを使用します。

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
$


blog comments powered by Disqus