if, for, while は1行でも中括弧(ブロックマーク)で囲う 1


どうも、スィンです。

Apple史上最悪のセキュリティバグか、iOSとOS XのSSL接続に危険すぎる脆弱性が発覚──原因はタイプミス?

2014年にこのようなニュースが有りましたが、これは

「コピペが悪い。またコピペしたでしょ!」とか
「こんなの書いてて気づかないのかよ!」とか
「邪悪なgotoをなぜ使ってるんだ!」とか
「単価の低いプログラマを使っているのか!」とか
「結局 fail に飛ぶのに失敗と判定されないのはなぜなんだ!」とか

まぁ、皆さんも色々と指摘したい箇所はあるかと思いますが、一番大きな問題は、

「テストしてないでしょ。テスト漏れでしょ、ちゃんとテストしろよ!」

ってことなんですよね。テストしてください。

では、テストをちゃんとすべきなのはわかって頂けた上で、このようなことを防げるよう日常的に対策をしておきましょう。

[code lang=”java” collapse=”false”] package net.sinrpoject.lesson;

public class IfElseSample {

public static final String TEXT_SPLITTER = " ——- ";

public static final String TEXT_OK = "OK";
public static final String TEXT_NG = "NG";

/**
* @param args
*/
public static void main(String[] args) {
String value = TEXT_OK;
String value2 = TEXT_NG;

System.out.println(TEXT_SPLITTER + "func1(\"OK\")" + TEXT_SPLITTER);
func1(value);

System.out.println(TEXT_SPLITTER + "func1(\"NG\")" + TEXT_SPLITTER);
func1(value2);

System.out.println(TEXT_SPLITTER + "func3(\"OK\")" + TEXT_SPLITTER);
func3(value);

System.out.println(TEXT_SPLITTER + "func3(\"NG\")" + TEXT_SPLITTER);
func3(value2);
}

public static void func0(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");

System.out.println("終わり");
}

public static void func1(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
System.out.println("OKの2行目です。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");
System.out.println("NGの2行目です。");

System.out.println("終わり");
}

public static void func2(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
}

System.out.println("終わり");
}

public static void func3(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
System.out.println("OKの2行目です。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
System.out.println("NGの2行目です。");
}

System.out.println("終わり");
}
}
[/code]

「func0() を作ったんだけど、OK と NG のケースにてそれぞれ2行以上処理したくなったので func1() にしました!」

というところで意図しないバグが生まれています。func1() では 引数が “OK” の場合に「NGの2行目」が意図せず出力されています。逆に引数が “NG” の場合も「OKの2行目」というのが出力されてしまっています。この手のコードで行を追加するときにこの問題が発生することがあります。行を追加するときは「中括弧がついていなければ付けないと・・・」という判断と対応が必要になります。

対策として

「if, for, while は、本体が1行でも中括弧(ブロックマーク)で囲う」

ことをコーディング規約にしてしまいましょう。func2(), func3() はそのように変更したものです。また、どちらも ture になる条件式ではないため「if-else」に変更しました。

インデントはただの見た目です。ただし人間はその見た目に騙されるのです!対策をしておいて損はないです。忘れ物が多い人は、前日に準備すると忘れ物が減りますよね。それと同じです。

バグ発生させた上司Aさん「でも、カッコがない方がカッコイイだろ!」
バグ対応した部下Bさん「何時間も原因を探した結果がカッコ不足が原因って、カッコつけたはずなのに超絶カッコ悪いっすよね!」
バグ発生させた上司Aさん「省略形があるのに使わいとかバカっぽいだろ!」

真実は小説より奇なり。

今回はここまで!ではでは!

自分も使う人も毎日楽しくなるアプリを制作。よくしゃべる人。

Windowsアプリ(医療システムや販売管理)、Webアプリ(グループウェアや中古車販売)、クラウドシステム構築など、業務システムのエンジニアとして15年以上の経験を積んで独立。

朝日新聞で紹介されたTwitterアプリ「Tweecha」や新アプリ「Txiicha」、簡単に割引や消費税計算ができる電卓「電卓っちゃ」、脳トレゲームなどを制作。

趣味は楽器演奏、映画・アニメ・ドラマ鑑賞とゲーム。

アプリを一緒に作りたいエンジニア、デザイナーさんなどは @iam_o_sin までご連絡下さい。

システムやアプリ制作、Webサイト構築等のご相談、取材依頼は「お問い合わせ」からご連絡下さい。

0

Leave a comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

One thought on “if, for, while は1行でも中括弧(ブロックマーク)で囲う