さて、次はファイル名や表示行数を指定できるように修正しよう。
引数は、Cのargv相当がSys.argvに入ってくるが、自分でパースするのはめんどうだ。 もちろん、標準ライブラリでパースできる。Argモジュールを使う。
以下の手順を踏む。
- 引数で指定された情報を格納する参照を定義する
- どんな引数がくるのか、定義を作る
- パースする
詳しいことは、 http://caml.inria.fr/pub/docs/manual-ocaml/libref/Arg.html を読む。 手順2のanon_funに何を指定するのかわかりにくいが、要するにフラグ無しの引数の扱いを指定すればいい。
tail -n 5 filename
に対応したかったら、
let n = ref 5 (* 表示する行数 *) let inputfile = ref "" let spec = [("-n", Arg.Set_int n, "Number of lines")] let () = Arg.parse spec (fun s -> inputfile := s) "" (* ファイルを全行読み込む *) let fi = open_in !inputfile let lines = let lst = ref [] in let eof = ref false in while not !eof do try lst := !lst @ [(input_line fi)] with End_of_file -> eof := true done; !lst let () = close_in fi (* 行のリストの最後n行だけ取り出す*) let rec tail lst = match lst with [] -> [] | first :: rest -> let last = tail rest in if List.length last > !n - 1 then last else first :: last let () = List.iter print_endline (tail lines)
これでOK。以外とバリバリrefを使うのである(笑)。