ブレース(波括弧)の省略記法とフリーフォーマットの仕組みを取り入れた多くのプログラミング言語で利用可能なテクニックを紹介する。
目次
- ブレースの省略について
- if if イディオム
- if try イディオム
- else switch イディオム
- for if イディオム
- if else トグル・イディオム
- if false コメントアウト・イディオム
ブレースの省略について
C言語やJava, PHP, C#, JavaScript等のプログラミング言語では、if文やelse文のブレース(波括弧 = {}
)を省略できる。
// Before
if (a) { a(); } else { b(); }
// After
if (a) a(); else b();
else文に対応する文の部分には、一般的な処理やブロック文だけでなく、if文を配置することもできる。
// Before
if (a) {} else { if (b) b(); }
// After
if (a) {} else if (b) b();
実は、普段我々が無意識の内に使っているelse if
という構文は、このブレース省略の仕組みによって実現されているのである。
より詳しい説明は以下のページで行っているので参考にされたい。
「else if」文は存在しない【美しきプログラミング言語の世界】
if if イディオム
ブレース省略の仕組みを応用すると else if 構文だけでなく、if if という構文も実現できるようになる。
// あまりメリットはない
// if (a && b)と同等の処理
if (a) if (b) {
print(a);
print(b);
}
// プリプロセッサとの組み合わせ
#ifdef DEBUG
if (f("select v from t where f = 'a'"))
#endif
if (b) {
print(b);
}
if try イディオム
if if の発想は if try イディオムとしても応用できる。
if (io) try {
io.close();
} catch (IOException e) {
e.printStackTrace();
}
else switch イディオム
また else if の応用として、Javaの世界には else switch イディオムがよく使われている。
if (string != null) {
System.out.println("(null)");
} else switch (string) {
case "a" System.out.println("A");
case "b" System.out.println("B");
}
for if イディオム
排他処理/バリデーション処理を簡潔に記述できる。
for (Result r : rs) if (r != null) {
System.out.println(r);
}
auto a = {1, 2, 3, 4, 5, 6, 7, 8};
for (i : a) if (1 & i) {
printf("%d, ", i); // "1, 3, 5, 7, "
}
if else トグル・イディオム
一行目のコメントを外すことで二行目の処理が事実上コメントされるというテクニック。
//if (1) delete(); else
insert();
↓
if (1) delete(); else
insert(); // 実行されなくなる → 逆に`delete()`が実行される
こちらの方法だと一行目のコメント削除と、二行目のコメントアウトで二度手間となる。
//delete();
insert();
if false コメントアウト・イディオム
こちらは主に複数行のコードブロックに対して使われるコメントアウトのテクニックであり、デバッグ中や手探り的な開発シーンで重宝する。
/* Before */
// if (a) {
// print(a);
// }
/* After */
if (false) if (a) {
print(a);
}
こうすることでif (a)
以降のコードはデッドコードになり、実行されなくなる。これによって事実上のコメントアウトが実現される。
C言語やJavaなどのコンパイラ言語の世界では、このようなデッドコードを警告してくれることが多く、コメント解除のし忘れを回避できるという利点もある。IDEによる警告位置へのジャンプ機能も活用できる。いかにもハッカーが好みそうな、地味に便利なイディオムとも言える。
以下のような改行記法を用いれば、コメント状態を必要に応じて瞬時に切り替えることも可能となる。
/* コメント状態 */
if (false)
if (a) {
print(a);
}
/* コメント解除状態 */
//if (false)
if (a) {
print(a);
}
プリプロセッサを活用した地味に便利なハックもある。
#ifdef FLAG
if (false) // 環境に応じてコメントアウトされる
#endif
if (a) { // FLAG有効時でも構文チェックが行われる
print(a);
}
このイディオムの特徴は、コメントアウト対象の処理に対して、構文チェックが働く点である。一般的なコメント文やマクロによるコメントイディオムが施されたコードには、構文チェックが行われない。外部ツールによるリファクタリングの対象から外れる恐れもある。
// if (a) {
// print(a);
// }
#if 0
if (a) {
print(a);
}
#endif