読者です 読者をやめる 読者になる 読者になる

Yokohama.groovy(仮) #1 メモ

経緯

先日の TDD in Action に参加した後、Groovy や Gradle についてもっと理解を深めたいなと思っていたところ、一緒にペアプロしてもらった @grimrose さんや @shinyaa31 さんなどと Twitter でも盛り上がり勉強会を開催することになりました。

場所は、横浜近辺の人なら知ってるかもしれないコワーキングスペース タネマキさん。
今のところ少人数の会なので、大きなハコを借りるとかは考えてません。

今回のエントリも自分のためのメモです。

勉強会の方針

現在 Groovy と言えばこの本ということで『プログラミング Groovy 』を写経します。

プログラミングGROOVY

プログラミングGROOVY

Groovy の写経を中心に、Spock、Gradle などを絡めて学習したいですねという方針です。
私は都合が悪くて参加できませんでしたが、第 0 回でこの辺の方針が決まりました。

やったこと

事前にある程度の環境設定は各自でしてきていたので、@grimrose さん作成の build.gradle スクリプトを使って、プロジェクト環境を整えました。
TDD in Action でのペアプロ時に使ったものと同じで、依存関係等も含めて、IntelliJ IDEA 用のプロジェクト構成がすぐ作れるスグレモノ。
これにより、全員同じプロジェクト構成となりました。

確認のために Spock 公式ページにあるコードを実行してみて、環境準備終了。

ここから、ようやく写経です。
今回のメインは、wordCount.grovy スクリプト

引数付きのスクリプト実行で、ちょっと手間取りましたが問題なく動作しました。
メニューの Run → Edit Configrations → Script parameters に引数を設定して実行しました。

引数を簡単に変更できるようにするため GroovyShell からも動かしてみたかったのですが、うまく行きませんでした。
次回に向けての課題ですかね。*1

全員が動作確認できたところで、スクリプトをいじったり、気になる点をディスカッションしたりなどしました。
私はクロージャ周りがもやっとしていたので、it を別の名前に変更、メソッドの() 内にクロージャを引数として設定、クロージャの引数追加など、色々試して遊んでました。

そんな感じで、タネマキさんが閉まる22 時までわいわいやって終了しました。
環境準備にちょっと手間取ったために手を動かす時間が少なかった気がしますが、次回からは改善できるはず。

しばらくは隔週でゆるく小さく開催する予定です。

その他

クロージャ周りは本の別の章で出てきますが、やってて気になったことがあったので帰ってから調べてみました。
気になったことはこの辺。

  • File の eachLine に渡すクロージャは、引数 1 つでも 2 つでも動作した。
    • 1 つの場合は、各行の内容、2 つの場合は、2 つ目に 1 から始まる連番が格納されていた。
  • 結局、暗黙の引数 it には何が入ってるの?
    • もちろん、メソッドごとに違うんでしょうけど。

GDK のドキュメント等を読んでみました。
eachLine
each

これを読むと eachLine の方は、クロージャの引数についてはっきり書いてあり、内容も試した結果どおり。
気になったのは、each の方で、各要素が渡ってくるらしい。
ってことは、List の場合はいいとして、Map の場合はどうなんのかなーと思ったので試してみました。

使ったデータはこれ。Map の List です。

def mapList = [[name:"cola", price:120],[name:"water", price:100]]

まずは it の内容を確認してみます。

mapList.each {
    println it
}

結果

[name:cola, price:120]
[name:water, price:100]

引数を 2 つにしてみます。

mapList.each {a, b ->
    println a
    println b
}

結果

Exception thrown
以下省略

it に Map が格納されているのが分かったので、さらに each してみます。

mapList.each {
    it.each {
        println it
    }
}

結果

name=cola
price=120
name=water
price=100

Map なんだから、key と value 持ってるだろうということで引数を 2 つにしてみます。

mapList.each {
    it.each {a, b ->
        println a
        println b
    }
}

結果

name
cola
price
120
name
water
price
100

引数を 3 つにしてみます。

mapList.each {
    it.each {a, b, c ->
        println a
        println b
        println c
    }
}

結果

Exception thrown
以下省略

引数が複数の状態で 1 つを it にしてみます。

mapList.each {
    it.each {it, b ->
        println it
        println b
    }
}

結果
コンパイルエラー

ちょっとはもやっと感が解消されたかな。

GDK のメソッドの詳細を知らずに写経しただけだったので it に何が入っているのかわからない状態でクロージャ内の処理を自分で書くという辺りが混乱してたんじゃないかと。

GDK*2の引数としてのクロージャは、引数だけ定義されていて、後は自分で定義しろよと理解しました。
で、その引数の定義は GDK のドキュメント読めと。

でも GDK の定義にも、クロージャの引数についてはっきり書いてない場合もあるので、動かして試してみるが正解なのかなー。
この辺に書いてあるぞ!もっとよく読めよ!などのご指摘があればよろしくお願いします。

ということで、本を読み直します。

*1:そもそも、対話的インターフェースだったので使用目的に合ってるかも確認要です

*2:というか自分で定義したものを含めてメソッド全般