サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

if〜else 文の周辺のコメントの書き方と注意事項

はじめに

 if〜else 構造と、付随するコメントの書き方で、以下のようなコードを見ました。

/* --- List 1 --- */

// 20 以上の場合
if (age >= 20)
{
    console.log("20以上です");
}
// 未成年の場合
else
{
    console.log("未成年です");
}

 上記 List 1 について「コメント内容」「位置」「書き方」について思うところを書きます。

 その前に、最近の自分はこんな書き方はしません。というか、最近はこういう場合にコメントは書きません。先にその理由について記します。

コメントをあまり書かない理由

 if 文の周りは、可能な限り短く、読みやすくコードを書くようにしているためです。

if (array.HasRows())
{
    PrintList(array);
}
else
{
    WriteLog(NO_DATA_MESSAGE);
}

 条件文も読んだらすぐにわかるように、中の処理もメソッドを分けて1行だけにして、これくらいなら、コメントを書くまでもないですよね。List 1 も以下のように書けば、意図は明確になりコメントは不要になるでしょう。

var isAdult = (age >= 20);
if (isAdult)
{
    // 省略
}
else
{
    // 省略
}

コメントの内容について

 コメントには、その直下のコードの意図を表すという原則があるとするならば、if 周りのコメントは、以下のようになるはずです。

// 何の判定を行うかを書く
if (flag)
{
    // 真の時に、どんな処理を行うかを書く
}
else
{
    // 偽の時に、どんな処理を行うかを書く
}

 つまり List 1 の最初のコメント「20 以上の場合」は「判定の結果」を表しているのであって、「判定したい内容」ではありません。直下のコードの意図を表していません。

 サポンテなら以下のようなコメントにします(位置は直さず)。

// 20 歳以上かどうか判定する
if (age >= 20)
{
    // 20 歳以上であることを表示する
    console.log("20以上です");
}
// 20 歳以上ではないと判定する
else
{
    // 未成年であることを表示する
    console.log("未成年です");
}

コメントの役割

 コメントには「直下のコードの意図を表す」という使い方の他に、いくつかの役割があります。よく「意図を書け」とは言いますが、サポンテはそれだけではないと思っています。

  • 複雑なルートパスである場合に、 そこを通るのはどういう状態か を書く。
  • 処理ブロックを要約する「見出し」として書く。

 いろいろな意図をもって書かれるコメントがあるため、どのような意味で書いたコメントか、プレフィックス(接頭辞)をつけていたこともありました。以下の例のように。

/* --- コメントの書き方・プレフィックスと、伝えたい意図の例 --- */

// 行コメント:直下の処理の要約を書く

// -----
// 見出しコメント:直下の処理ブロックの要約を書く
// -----

// > 状態コメント:このルートを通るのはどのようなケースなのかを書く

 ただ、それが広く世界に共有できていなければ謎の記号でしかないのと、上述のようにコード自体をわかりやすくすることで対応できるため、やめました。

コメントの位置

 List 1 の else の前を見ると、} との間に1行とってコメントを入れています。これはもしかしたら if〜else 構造をブロックとして見ているのでしょうか?

 if (flag) {〜}else {〜} を、関数のような「処理ブロック」だとイメージしたのでしょうか。もちろんメソッドじゃないし、処理のブロックというなら、サポンテは以下のようにイメージします。

if (flag)
{
    // -----
    // 処理のブロック
    // -----
}
else
{
    // -----
    // 処理のブロック
    // -----
}

 ですので、やはりコメントは {} の間に、インデントしてから書く方がいいのではないかと思います。

コメントの書き方

 まあここまでは趣味の範囲かもしれません。ですが、次の件はぜひ留意して欲しいです。

 最近では、こうした記法のゆれを統一するために、便利な整形ツールを用いることがあります。そのとき「これからは、以下のような書き方で統一しよう」「いままでのコードは整形ツールで自動的に一括変換するよ」と、決まったとします。

if (flag) {
    // 処理
} else {
    // 処理
}

 { の位置が、行末に移動していますね。もしこの時、整形ツールが List 1 を以下のように書き換えてしまったらどうしましょう。

// 20 以上の場合
if (age >= 20) {
    console.log("20以上です");
} // 未成年の場合 else {
    console.log("未成年です");
}

 文法エラーになっていますね(実話)。

 以下のような書き方も、同様のリスクがあります。

if (age >= 20) // 20 以上の場合
{
    console.log("20以上です");
}
else // 未成年の場合 
{
    console.log("未成年です");
}

 ですので、もし if 文の近くでこうしたコメントを書きたいのであれば /*〜*/ の書き方のコメントを使用してください。そうすれば、整形ツールの適用が即致命症にはなりません。

if (age >= 20) /* 20 以上の場合 */
{
    console.log("20以上です");
}
else /* 未成年の場合 */
{
    console.log("未成年です");
}

 そのうち整形ツールの方がどんどんスマートになって、うまく対処してくれるようになるかもしれません。しかし、案外とレガシーな技術に頼っている現場は多いものです。

 ところによっては「コメントは全て /*〜*/ の書き方で書くこと」としているかもしれません。しかしそう決まる前に、既にソースコード資産が多く存在するということも、よくあります。

 /**/ の入力が面倒なら、IME に「こめ」とかで辞書登録しておく手もあります。

いろいろな人たち

 今回の記事を書くにあたって、調べてみたらいろいろな書き方をする人がいるんだなと思いました。