よりそいAda
同じ問題をAdaでやってみた。
まずはEmacsを起動します。使い回せそうなEmacsが有ればそれを使いますが、Emacsごとに開いているファイルの文脈が有るので、目的ごとに結構たくさんEmacsを走らせます。2重screenの兼ね合いもありますし。とりあえず僕もボディファイルから作ります。ヘッダは後。
yudai@lysithea% emacs yorisoi.adb
手癖でとりあえずの構造を作ります。
procedure Yorisoi is
begin
end Yorisoi;
おもむろに副プログラムの構造ができあがります。
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
begin
end Count_Comma;
begin
end Yorisoi;
「数えるための変数が必要だなー」
procedure Yorisoi is
function Count_Comma (About :out String) return Integer is
Count : Integer := 0;
begin
end Count_Comma;
begin
end Yorisoi;
「文字列をイテレートするにはforかな」
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
end loop;
end Count_Comma;
begin
end Yorisoi;
「関数名からして決め撃ちだし、いいよハードコーディングで」
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About(I) = ',' then
end loop;
end Count_Comma;
begin
end Yorisoi;
「増やしてif閉じて」
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About(I) = ',' then
Count := Count + 1;
end if;
end loop;
end Count_Comma;
begin
end Yorisoi;
「あとは戻すだけ」
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About(I) = ',' then
Count := Count + 1;
end if;
end loop;
return Count;
end Count_Comma;
begin
end Yorisoi;
「適当に実験しよう。標準出力にでも出せばいいよね」と思いつつ、Integer_Text_IOを呼ぶのはめんどくさいので、Integer'Image
する。
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About(I) = ',' then
Count := Count + 1;
end if;
end loop;
return Count;
end Count_Comma;
begin
Put_Line (Integer'Image(Count_Comma ("Here, Here, and Here,")));
end Yorisoi;
パッケージ読み込み。
with Ada.Text_IO; use Ada.Text_IO;
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About(I) = ',' then
Count := Count + 1;
end if;
end loop;
return Count;
end Count_Comma;
begin
Put_Line (Integer'Image(Count_Comma ("Here, Here, and Here,")));
end Yorisoi;
できたかな? ここで一度コンパイル。
yudai@lysithea% gnatmake yorisoi gcc -c yorisoi.adb gnatbind -x yorisoi.ali gnatlink yorisoi.ali
問題なさそう。実行。
yudai@lysithea% ./yorisoi 2
良さそうだな。
後は、コードをきれいに。コーディング規約重要。個人的にはDoDのよりもNASAのやつの方が好きかな。関数名の後に空白入れるとかそこら辺。
with Ada.Text_IO; use Ada.Text_IO;
procedure Yorisoi is
function Count_Comma (About : String) return Integer is
Count : Integer := 0;
begin
for I in About'Range loop
if About (I) = ',' then
Count := Count + 1;
end if;
end loop;
return Count;
end Count_Comma;
begin
Put_Line (Integer'Image (Count_Comma ("Here, Here, and Here,")));
end Yorisoi;
確認してみる。gmkがgnatmake -gnaty3abefhiklM120nprtへのaliasで、これがNASAのコーディング規約に従ってる設定。オプション自体の詳細はマニュアル参照の事。gnat check使ってもいいかも。
yudai@lysithea% gmk yorisoi gcc -c -gnaty3abefhiklM120nprt yorisoi.adb gnatbind -x yorisoi.ali gnatlink yorisoi.ali
というわけで完成。
Adaだと固定長文字列の操作が楽だなー。ミスが入り込む余地が無い。今回は問題が簡単だったのでAdaのいいところがあまり出なかったかも。もっと難しい問題だとコンパイル時エラーの検出と親切すぎる警告文がとてもありがたいんですが。