2012年4月30日月曜日

鹿駆動勉強会とはなんだったのか

プログラマーズナイトからその流れで鹿駆動勉強会というハードな二日間が終了しました。
blogを書くまでが勉強会なので、まとめておこうと思います。

■プログラマーズナイト #3


http://atnd.org/events/27094

プログラマーが集まって、DJとかLTとか夜通し騒ぐ、というイベント。
なんかもう、とにかくやばかったです。

ぼくもテキーラ・レッドブル飲みながらJoJo LTしてきました。
http://www.slideshare.net/daiksy/jojo-8930790
あのネタをやるのはこれで3回目なのですが、今回も好評で、完全にぼくの持ちネタです。

初演を見て下さった人から、コピペ開発はよくないよという主旨にもかかわらず、スライドをコピペしてるじゃねーか、という辛辣なツッコミをいただきましたw

■そして鹿駆動


同僚の家で仮眠をとらせてもらい、奈良へ鹿駆動勉強会に参加しに行きました。
こちらはスタッフとしての参加です。
ATND: http://atnd.org/events/24587
告知記事: http://el.jibun.atmarkit.co.jp/topics/2012/04/post-8fd1.html

当初は完全に勢いだけのスタートでした。
参考「Togetter:奈良で勉強会しようず」http://togetter.com/li/244813
ただ、同じ方向を向いてる仲間が何人かいて、みんなが本気を出せばこんな勢いだけの企画も成立してしまうんですね。

結果100人を超える参加希望者と、20人のスピーカーと、奈良の能楽ホールというあり得ない勉強会が実現してしまいました。

ぼくたちはITのプロとして仕事をしています。数人から数十人のチームを組んで、要望を具体化し、手順を経てコンピュータソフトウェアという成果物を作り出します。

今回の鹿駆動では、当初の思いつきから実現にいたるまで、いろいろなことがありました。
当初は思いつきで、10人くらいで奈良で勉強会をしたいといういつもの仲間うちの勉強会のノリでした。
そこへ、能楽ホールというエッセンスが加わり、能楽ホールでなら発表してみたいというスピーカーが集まり、次第に形を変えて規模も大きくなりました。
時間が経つごとに状況が変わり、ぼくたちスタッフも何度か打ち合わせをして、その変化する状況に対応しながらコツコツと実現へのステップを組み立てて行きました。

これらのプロセスは、ITのプロとしての経験があってこそやり切れたという側面はあると思います。

そして何より感謝したいのは、IT勉強会はほんとうにすべての参加者の善意で成り立っているということです。

スピーカー、参加者、スタッフ。彼ら全員が「面白そうだからやってみよう」「楽しそうだから行ってみよう」というモチベーションで少しずつの善意を持ち寄って、ここまで大きな企画が実現したのです。

企業スポンサーがついたわけでもない、個人の善意の集まりだけで、鹿駆動勉強会みたいな企画が実現できてしまうITという業界をぼくは誇りに思います。



懇親会もすごく盛り上がったし、すごい勉強会でした。
みなさん、本当にありがとうございました。

「Togetter:鹿駆動勉強会」http://togetter.com/li/295148

ニコニコ超会議の裏でTitterトレンドに#shikadrivenが上がるとかありえないだろJK

■もうひとつの奇跡


今回の鹿駆動勉強会は、遠方からお越しの方がたくさんおられました。
その中のお一人から、とてもステキなフィードバックをもらいました。

去年、東京カルチャーカルチャーでITコミュニティ夏祭りというイベントを開催しました。
http://daiksy.blogspot.jp/2011/09/it.html

このイベントをきっかけに勉強会に参加するようになり、その流れで鹿駆動に遊びに来た、という人がいらしたのです。

小さなことですが、自分たちの活動が他の人になにかしらの影響与えているのだなー、と幸せな気持ちになれた出来事でした。

2012年4月17日火曜日

【Scala】コンストラクタ実装したtraitをobjectにmixinしたらなるほど、こうなるよな、という話

あるリクエストを受け取ったときに、ユーザに関連する情報を一括で削除したい、という要件があった。

対象のテーブルがたくさんあったので、いちいちhoge.deleteみたいな記述を羅列するのは避けたい。削除対象テーブルは今後の開発で余裕で増えるだろうし。

で、こんなコードを書いてみた。

    object CleanerContainer {
        import scala.collection.mutable.ListBuffer
        private val list: ListBuffer[Cleaner] = new ListBuffer[Cleaner]

        def append(cleaner: Cleaner) = this.list.append(cleaner) 

        def execute(userId: String): Unit = list.foreach(_.clean(userId))
    }

    /**
    * コンストラクタで自分自身をCleanerContainer に追加するので、
    * これをmixinするだけでCleanerContainer.executeの処理対象になるはず。
    */
    trait Cleaner {
        CleanerContainer.append(this)

        def clean(userId: String): Unit
     }

     /** DBのCRUDを実装したmodelのコンパニオンオブジェクトと仮定  */
     object hogeModel extends Cleaner {
         override def clean(userId: String) = {
             hoge.delete(userId)
         }
         // (以下の実装は省略)
     }

CleanContainerは、一括削除の対象となるmodelをListで保有し、executeでそれらのcleanメソッドをまとめて実行する。

CRUDを実装しているmodelのコンパニオンオブジェクトが、Cleanerというtraitをmixinすることで、Cleanerのコンストラクタで自分自身をCleanContainerに追加しているから、hogeModelのようにclean関数に自信の対象レコードを削除する処理を記述すれば、CleanContainer.executeを任意のタイミングで実行することで、対象のデータを一括で削除できるはず!!!

で、意気揚々と実行してみたが、全然データが消えない。

…あ! objectにmixinしたtraitのコンストラクタ実装って、objectが最初に呼ばれたタイミングでないと実行されないじゃん!! シングルトンオブジェクトなんだからそりゃそうじゃん!!!

てっきりobjectってアプリケーションが起動したタイミングでオブジェクトが生成されるものだと勘違いしていたという、失敗談でした……。