ifの中にifを書いていったら、三段目で自分が何を判定しているのか分からなくなった
条件をひとつ足すたび、コードが右へ右へずれていく。
「だめな場合を先に片づける」と書き方を変えたら、同じ処理がずいぶん読みやすくなった。
スタンプラリーの機能を作っていたときの話だ。
チェックインのボタンを押されたら、その人が本当にそこに来ているのかを確かめて、まだ押していない場所なら記録する。
言葉にすればこれだけの処理なのに、書き上がったコードは画面の右のほうまで階段のようにずれていた。
条件が増えるたび、右へずれていく
最初は素直だった。
ログインしているかどうかを確かめる。
そのifの中に、位置が取れているかどうかを確かめるifを書く。
その中に、距離が近いかどうかのifを書く。
その中にもうひとつ、今日すでに押していないかのifを書く。
四つ目を書き終えたところで、自分がいまどの条件の中にいるのか分からなくなった。
閉じかっこの数を数えて、対応する行までスクロールして、また戻る。
条件そのものは難しくないのに、形のせいで読めなくなっていた。
「だめな場合」を先に片づける
教わったのは、順番をひっくり返すやり方だった。
やりたいことを内側に抱え込むのではなく、できない条件を見つけた時点でそこで打ち切る。
if (ログインしていない) { エラーを返して終わり }if (位置が取れていない) { エラーを返して終わり }if (距離が遠い) { エラーを返して終わり }if (今日すでに押している) { エラーを返して終わり }チェックインを記録する
並べ替えただけで、階段が消えた。
上から順に、断る理由が四つ並んでいて、全部くぐり抜けたものだけが最後の一行にたどり着く。
入れ子だった頃と、やっていることは何ひとつ変わっていない。
この書き方は、読む人にも親切だった。
「この処理はどういうときに失敗するのか」を知りたい人は、上の四行だけ読めばいい。
成功したときに何をするのかは、いちばん下にひとつだけ書いてある。
入れ子が減ると、確認するのも楽になる
先日書いたテストの話にもつながる。
入れ子が四段あると、条件の組み合わせが頭の中で掛け算になっていく。
どこを通ってどこを通らないのかを追いきれず、確認する気力がなくなる。
断る条件が縦に並んでいれば、確かめることは単純になる。
ログインしていないときに断るか。
遠いときに断るか。
ひとつずつ試せばいい。
形を変えただけなのに、後の作業がまるごと軽くなった。
それでも深くなるときは、条件に名前を付ける
並べ替えても長くなる場合がある。
そういうときは、条件の中身を別のところに追い出して、名前だけ残すようにしている。
if (距離が遠い) の中身は、実際には緯度と経度から距離を計算して、それを設定値と比べる何行かの式だ。
それをその場に書くと、読む人はまず計算式を読まされる。
「近くにいるか」という名前の関数に押し込んで、呼び出す側には名前だけ置く。
読む人は、中身を知りたくなったときだけ見に行けばいい。
コードを書き始めた頃は、動けば同じだと思っていた。
実際、動くという意味では同じだ。
違うのは、三か月後に自分が読んだときの速さのほうだった。
右に伸びていくコードを見かけたら、いまはいったん手を止めて、断る条件から書き直すことにしている。
※運営者が個人で書いているnoteです。