お断り: この記事の内容は、所属先の見解ではありません。
わりと何でもありのPHP界隈ですが、長年その状態を放置してきたため様々なスタイルのコードが存在することになり、PEARのようにまともにメンテナンスされてないコードを生み出してしましました。
さすがに何かしらの標準が必要では? ということで、PHP-FIGという組織がPHPに関するコーディングスタイル、autoload仕様、インターフェイス仕様を決めており、事実上の標準になっています。
PHP-FIG発足とほぼ同時に制定されたPSR-1, PSR-2はコーディングスタイルに関する標準で、PSR-1が基本的な内容、PSR-2がそれに追加してカッコの位置、スペースの入れ方、インデントのとりかたなど細かい内容になっています。
PSR-1は誰でも割りと受け入れられやすい内容だとは思いますが、PSR-2はコーディングスタイルに深く踏み込んでるので、人によっては異論があると思います。
特に個人的に受け入れがたいのが2つあります。1つ目は
制御構造の開始時は、その後に1スペースを開けなければなりません。メソッドや関数の呼び出しはスペースを開けてはいけません。1
というものです。
つまり、if
やfor
、while
、do
、switch
とその次のカッコとの間にスペースを入れろ。というものですね。
if($var == "abc"){
}
if ($var == "abc") {
}
スペースを入れる必然性がよくわかりません。実際のコードではスペースを入れるほうがむしろ少数派のように思えます。なんでわざわざスペースを置くことを決めたんでしょうか? 別にそこまで決めなくても良かったのではないかと思います。
そして、もう1つ。こちらが本題。
switch制御は下記のようになります。 括弧、スペースの位置に注意してください。 case文はswitchからインデントし、break(またはその他の終端キーワード)は、case内本文と同じレベルのインデントで揃えなければなりません。 また意図的に処理スルーさせる場合は「// no break」等、コメントしなければなりません。
という部分です。case
節はswitch
文からインデントしろ。と言ってるわけですね。
switch($var){
case 'A':
break;
case 'B':
break;
case 'C':
break;
default:
}
switch ($var) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
default:
}
こちらについては、PSR-2のスタイルのほうが一般的なスタイルだとは思いますが、個人的に書くコードでは断固case
をインデントしないスタイルを取っています。
なぜか。case
をインデントするとインデントは(制御構文における)分岐の範囲を表すものである。という原則を壊してしまうからです。
先程のコードを例に取ります。
switch($var){
case 'A':
break;
case 'B':
break;
case 'C':
break;
default:
}
このswitch
文によって分岐された各パターンがcase
節で表記されているわけであって、switch
文の結果がcase
節によってさらに分岐されるわけではありません。
このことは、if
〜else if
〜else
構文で書き換えてみればすぐにわかります。
if($var == 'A'){
} else if($var == 'B'){
} else if($var == 'C'){
} else {
}
ほら、見比べてみるとcase
節をインデントしない方が自然に見えませんか?
さらにcase
節をインデントするスタイルだとswitch
文の中にswitch
文を置いた場合、一番内側のcase
が3インデント分深くなってしまい、ますます分岐のネストとインデントのネストが乖離してしまいます。2
switch($foo){
case: 'A'
switch($bar){
case 'a':
break;
case 'b':
break;
}
break;
}
case
は文ではなく節であり3(goto
用の)ラベルに近い存在であるということ考えても、インデントしないほうが自然なんですけど、なんでインデントするとしてしまったのでしょう?
さて、ここで問います。「皆さん、なんでswitch
文のcase
節をインデントするんですか?」
追記: 「その定義だと、何もしない{}もインデントするなってことになるような。」とコメントを頂いたので、「(制御構文における)」という前提を追加しました。