Scala ことはじめ
今週Scala Coding DojoでMineSweeperというCode Kataをやる予定なのですが、いきなり行ってもただぼーと見ているだけで終わりそうなので、とりあえず自力で解いてみることにしました。
まずは「習うより慣れろ」だと思い、インターネット上のオンラインチュートリアルを2〜3読んだ後、いきなり書き始めることにしました。C++の方は本一冊読み終わりそうになってもいまだにコードかける気がしないのですが、Scalaだと「結構かけそうかも」と思わせてくれる分優秀です。ちなみにチュートリアルはこれが一番参考になりました。
最初はIntelliJのIDEやTDD用のツールを使おうと思ったのですが、どうもGUIはなかなか自習しずらく、「Hello World」も満足に出来ない有様。そういったツールの使い方はCoding Dojoで教えてもらうことにして、まずはテキストエディターとScala Interpreterを平行しながら始めました。Android開発などをかじっていたとき、どうしてもEclipseのようなIDEになじめなかった身としては、Rubyのように手軽に始められる気軽さが感じられました(そしてこれってプログラミング言語を習得するときにはとても重要)。
で、出来上がったのがこれです。
http://github.com/makoto/scala_kata/blob/master/minesweeper/first_trial.scala
初めて書いたので、かなり汚いコードかも知れませんが、これをもとに徐々に上達していければと思います。手元に本もない状態で、ひたすらGoogleで文法を調べながらでしたが、3〜4時間でできたところがなかなか学習しやすい(あるいは限りなくスクリプト言語にちかい)言語かなと思いました。もしリファクタリングのアドバイスがあればコメントいただけれるとありがたいです。
書いていてScalaの文法で気に入った点がいくつかありました。
- Initializer用メソッドを別に定義するのではなく、Class定義に直接引数を指定できる点。
class Field(
var height: Int,
var width: Int,
var first: Int,
var last: Int,
var input: List[String]
)
{…}
これでattr_readerとかも書かなくていいのはかなり楽です。あとここでタイプチェックしてくれるのでStringの数字("1")みたいなのを送ったらちゃんとここでキャッチしてくれるのも良い感じです。スティックタイプの利点を
var counter = 0;
と書いても良いし
var counter :Int = 0;
と書いても良いのは結構楽です。
特にメッソッドが以下のようにかけて短くなります。
def printOriginalBody = for (i <- first to last) println(input(i))
逆に驚いた点や、まだまだ使いこなしきれていないのはこんな点です
- Immutable な変数
"val"がImmutableなのは分かるのですがfor文の中のiもimmutable らしく、以下のようにiを代入しようとするとエラーが出ました。
Can not do this because i is immutable
for (i <- 0 to inputList.size - 1)
{
var headerList = List.fromString(inputList.first, ' ')
var height = headerList.first
i = i + height
}
こういう場合はwhile文を使うか再帰methodを使わなければならないようです。
- ArrayとListの使い分け
Array がMutable、ListがImmutableというのは分かっているのですが、Rubyにはない概念なので、なかなか意識して使いわけしきれてない気がします。
あと以下の2点はRubyではやりかた分かるのですがScalaでのやり方が分からず、冗長なコードになってしまいました(どなたかやりかたご存知でしたら教えていただけるとありがたいです)
- Arrayの開始点と最終点をもとに一部を切り出す
irb(main):003:0> [1,2,3,4,5][1..3]
=> [2, 3, 4]
- unless
irb(main):011:0> true unless 1 == 2
=> true
今週のDojoではどういった高度テクニックを習えるかたのしみです。それをもとに週末にもう一度書き直してみたいと思います。次回書き直す時は「全てをImmutableな方法で書く」など少し切り口をかえて挑戦してみたいと思います。あとcase文もScalaの特徴のようなのでそれも使える機会があれば使っていきたいです。