インデントについて考える 後編 | 悪態のプログラマ
2005年02月02日(水)

インデントについて考える 後編

テーマ:コーディング
タブが表現する幅は、環境によって違う。プログラマはそのことをよく認識し、タブの幅(桁数の設定)が変わっても、なるべくインデントが崩れないようにソースコードを書くべきである。それがソースコードの「読者」に対するマナーだろう。

といっても、それほど難しいことではない。一部の例外を除き、基本的にはスペースとタブを混在させないようにすればよい。

例えば、インデントが4桁の行はスペース、8桁の行はタブを使うといったことはよくない。タブが8桁(程度)であることを「読者」に強要するからである。

また、1行のインデントの中にタブとスペースを混在させるのもよくない。幅が固定のものと可変のものを合わせると「中途半端な可変」になり、崩れの原因となる。

ただし、この「混在させない」というルールには例外がある。

実は、タブを使ったインデントには、スペースを使うべき場面というのがあるのだ。


ソースコードのインデントでは、プログラムの処理的に意味のあるまとまりを「段落」とみなし、その段落をまとめて段下げする。段落の中に段落を作るような場合には、どんどん下げていくので、「階層」のようになる。

前編 で例に挙げたソースでいえば、関数や「if」、「for」の後の括弧 { ... } の中のような、いわゆる「ブロック」がひとつの段落である。

一方、段落とは無関係なところでインデントが必要なこともある。

行が長くなりすぎたのでやむをえず改行するとか、単にソースを読みやすくするために改行するようなことがあるだろう。このような便宜的な改行でできた行は、段落としては直前の行と同じ階層に属する。しかしながら、直前の行よりも深くインデントすることが多い。

このようなインデントでは、段落の階層が下がるわけではないので、ここでは「階層」と区別して「調整」と呼ぶことにしよう。

例えば、

1: void func2( int a,    // 階層0
2:       int b,    // 階層0 + 調整12
3:       int c ){   // 階層0 + 調整12
4:  if( a == 1 &&      // 階層1
5:    b == 2 &&      // 階層1 + 調整4
6:    c == 3 ){      // 階層1 + 調整4
7:   int d = a + b + c;   // 階層2
8:  }            // 階層1
9: }             // 階層0

というソースがあったとする(※1)。

1行目にはインデントがない。段落の階層の数は0である。

2行目は、1行目の続きを便宜的に改行しているだけなので、やはり階層はない。ただし、「int b」を1行目の「int a」の位置に揃えるために「調整」をしている。3行目も同様。

4行目からは、関数「func2」のブロックの中に入るので、階層が1つ下がる。

5行目も便宜的な改行なので階層は4行目と同じく1である。ただし、「b == 2」をすぐ上の「a == 1」にそろえるために、4桁分の「調整」が続いている。6行目も同様。以下省略。

ここで、インデントを作るときのルールは、

1. 行の先頭から、「階層」の数だけタブを打つ
2. 更に「調整」をしたい場合には、スペースを打つ

である。タブが先でスペースが後である。その順番が逆であってはならない(※2)。

例えば、上記の5行目を書くときには、タブを1つだけ打ち、それ以後はスペースを4回打つのである。

タブを「→」、スペースを「-」で表現すると、次のようになる。

1: void func2( int a,    // 階層0
2: ------------int b,    // 階層0 + 調整12
3: ------------int c ){   // 階層0 + 調整12
4: if( a == 1 &&     // 階層1
5: ----b == 2 &&     // 階層1 + 調整4
6: ----c == 3 ){     // 階層1 + 調整4
7: →→int d = a + b + c;  // 階層2
8: }           // 階層1
9: }            // 階層0

このようにすれば、タブの幅を変更しても、階層内の位置が崩れることはない(※3)。

現実には、「調整」の一部または全部をタブにしているソースをよく見かける。当然ながら、タブの桁数を変更すると崩れてしまう。ソースを読みやすくするはずの改行が、逆にソースを読みにくくしてしまうとは、皮肉なものである。


ここまで、インデントについて考えてきたが、インデント以外の場所でも、縦にコードを揃える必要があるようなところでは、タブは使わないほうがよい。

タブという特殊な文字は常に意識して、取り扱いには注意が必要である。

プログラミング向けのエディタ には、タブを目に見える形で表示できるものが多い。もし自分のエディタの画面にタブが表示されないようだったら、表示することができないかどか、設定等を確認してみるといいだろう。






※1
ここでは便宜上、タブの代わりに全角スペースを使用。なお、HTML の PRE タグが使えることが判明したので、今回から使用している。環境によってはきちんと見えないかもしれないが。。。

※2
タブの左(前)にスペースがくることはない。スペースに限らず、タブの左にはいかなる文字もないほうがよい。つまり、行頭以外にはタブを使わないということである。本文の例でいえば、コメント「//」の前などにタブを入れたくなるが、スペースにすべき。そうしないと、コメントの開始位置が縦に揃わなくなる(もっとも、揃える必要がない場合はタブを入れてもかまわないのだが)。

※3
階層をまたがって縦に並べるようなことをしていれば、ずれてしまう(上記の例で言えば、縦に並んだコメント「//」の部分がずれてしまう)のだが、そのような記述が必要なケースは稀だろう。



Code Complete第2版〈上〉―完全なプログラミングを目指して
スティーブ マコネル
日経BPソフトプレス (2005/03)
売り上げランキング: 4,432
おすすめ度の平均: 4.8
5 これを読まずしてソフトウェア開発ができるか?
5 職業プログラマーになりたいですか?
5 1歩上を目指す全ての開発者へ


ずばりわかる! Java Javaの良いコード、悪いコード
石原 直樹 河村 嘉之 丸の内 とら 米持 幸寿 日経ソフトウエア
日経BP社 (2006/03/09)

argvさんをフォロー

ブログの更新情報が受け取れて、アクセスが簡単になります

コメント

[コメントする]

Ameba人気のブログ

Amebaトピックス