OCaml Boot Camp

TDD Boot Camp名古屋一日目の成果を、2週間経過した今更まとめる。

環境設定

  • OCaml-3.11.2
  • findlib-1.2.5
    • OCamlのパッケージ管理的な何か。
ocamlfind -list

でインストールされているパッケージを確認できる

  • oUnit-1.0.3
  • extlib-1.5.1
    • たぶん便利な何か。
  • OMake-0.9.8.5-3-x86
    • ビルドツール的な何か。.dmgからインストール。portからもいけるらしい。
  • Emacs
    • おなじみの教祖
  • tuareg-2.0.1
    • Emacs用マクロ的ななにか
~/config/site-lisp/tuareg-2.0.1

に展開したのち、~/.emacsに下を記述する。

(add-to-list 'load-path "~/config/site-lisp/tuareg-2.0.1")
(add-to-list 'auto-mode-alist '("\\.ml\\w?" . tuareg-mode))
(autoload 'tuareg-mode "tuareg" "Major mode for editing Caml code" t)
(column-number-mode 1)

構成とお作法

  • OCamlではファイル(*.ml)をモジュールとして扱う。ファイルの命名はcamelCase(hogeFuga.el)で先頭小文字として、HogeFugaモジュールとして扱われる。
  • テストモジュールの命名はhogeFuga_test.mlみたいにするのが@mzp流。
  • omake(おーめいく。オマケではない)はビルドツール的な何か。
  • src、test下にOMakefileがある。その中のFILES配列の中身をビルド対象としている。
  • omakeから、コンパイルユニットテストを実行できる。-Pオプションが便利。ただ、上手くコンパイルできていないタイミングがあって、しばしばcleanを手動実行していた。
omake check # テスト実行
omake clean # クリーンに
omake check -P # ファイル更新をモニター(フック?)して勝手にテスト実行

作ったもの

http://github.com/katzchang/tddbcnagoya
適当な作業ディレクトリに移動して、

git clone git@github.com:katzchang/tddbcnagoya.git
テストコード

http://github.com/katzchang/tddbcnagoya/blob/master/test/fileStore_test.ml
テストコードは上から作ってます。

"存在しないキーでgetするとNoneがかえる" >:: begin fun () ->
  assert_equal None (get empty "hoge")
end;

これがテストの最小ブロックで、「>::」は続く関数に名前を付けてテストケースとするという演算子的な何か。
で、テストケースの配列(配列は「[]」で囲み、「;」で区切る)を作って、「>:::」関数によりその配列に名前を付けてテストケース群にし、run_test_tt_mainに突っ込んで実行させている。らしい。
後半、

assert_equal ~printer:Std.dump "A:a\nB:b\n" (dump (set_multi empty [("A","a"); ("B","b")]))

などとなっている部分がある。「~printer:Std.dump」をカマすと、「expected "hoge" but got "fuga"」みたいな、すこし情報が見れるようになる(それ以外ではRED/GREENしかわからない)。

プロダクトコード

http://github.com/katzchang/tddbcnagoya/blob/master/src/fileStore.ml
特筆すべき点は…よくわかりませんw
途中、型情報を定義するものを作ったはずだけど、残ってない?

雑感

  • optionに馴染みがない(Some "fuga"とか)
  • 関数の意味の読み方。
# List.fold_left;;
- : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>

このときのListのfold_leftは、

(ある型aとある型bをうけて型aを返す関数)と型aのものと型bを要素とするlistを受けて型aを返す関数

と読むことができる。使用例として:

let dump store =
  List.fold_left (fun s (a,b) -> a ^ ":" ^ b ^ "\n" ^ s) "" store

dumpはstoreをパラメータとする関数であり、タプル(a,b)の中身を文字結合しつつ、初期値「""(空文字)」にどんどん足していくんだよ(fun sのsを使って)、storeの中身を、みたいな意味になる。翻訳難しい。

  • ペアプロでは、プログラムレベルに実力がありすぎると一方的に教わるだけになってしまう。
    • そのうち、ペアは横で別のことをやり始めるw
  • その言語をある程度習得して、ペアプロ経験もある人の場合、こんな機会では別の言語で参加してみるのも面白いかも。
  • TDD Boot CampというよりOCaml Boot Campな一日でした。
  • Scalaもかっこいいコードだった(という記憶だけが鮮明に残っているが、中身は忘れている)
  • C++もやけに多く、Pythonはゼロ。地域でこんなに差がでるとは…。

二日目の話題、レガシーコード対策はあとでかく。