何故いわゆる直訳コメントを書いてほしくないのか

# 何故いわゆる直訳コメントを書いてほしくないのか
```php
$count = $count + 1; // カウントを1増やす
```
これこれ、こういうやつ。何故ダメなのか。
処理的にはインクリメントと同じだし、「カウントをカウント+1にする」よりはよっぽどマシじゃないか？

## しっくりこない理由たち
- とにかくコメント減らしたいから
- 情報量増えないから無駄だ
- そのうち実装と乖離して嘘になるじゃん

うん、上に書いたスタンスとも一致するね。じゃあこれらが理由かって？
違う、違う。
全くありえないとまでは言わないが、**この記事で言いたい理由**はこれらじゃあない。

## いわゆる直訳コメントを書いてほしくない、たった1つの理由

挙げたいのは1つだけだ。**直訳に見える誤訳になっている**かもしれないからだ。
「実装と乖離」という点は前掲したものと同じだが、誤訳はそのうちではない。**最初から**だ。

もちろん、誤訳ではないが意味のない直訳コメントもある。それらは不要ではあるが、あってもまぁどうでもいい。
しかし、読みやすくするためのコメントが誤訳になっていては、意味がないどころかトラップになってしまう。

では、ここで言う誤訳がどういうものかをでっち上げたコードを例に見ていこう。

### 直訳に見える誤訳？
```php
$count = $count + 1; // カウントを1増やす
```
さて、まず先程の`$count`の正体は何者だろうか。一体、何のカウンタなのか。
そして、どうみても直訳なのにどこが誤訳だというのか。
流石にこの1行じゃ正体も何もわからない。もう少し前後も見て探ってみるとしよう。
```php
public function getOneBasedRowCount()
{
    $count = $this->rowCount; // 行数を取得
    $count = $count + 1; // カウントを1増やす
    return $count;
}
```
どうやら`$count`は行数らしい。0オリジンの内部値から1オリジンにしたものを取得しようとしているようだ。
行数の話なのはメソッド名からして自明だし、`$rowCount`ではなく`$count`なのはまぁいいとしよう。

とはいえ、コメントでは流石にカウントじゃなくて行数って書こうか。
```php
public function getOneBasedRowCount()
{
    $count = $this->rowCount; // 行数を取得
    $count = $count + 1; // 行数を1増やす
    return $count;
}
```
はいこれで一件落着。しかし、「カウント」が誤訳はちょっと言い方が悪すぎるのでは？
この程度なら脳内補完で充分じゃない？カタカナ英語反対過激派？

……いやいや、待て待て。残念ながらまだだ。
カタカナ英語云々はともかくとして、そもそも誤訳は「カウント」のことではない。
**カウントを行数に読み替える**程度は脳内補完で十分なのはそのとおりだが……

### 誤訳のはじまり
脳内補完でカウントを行数に読み替えたことにして、もう一度見ていこう。

早速だが1つ質問だ。なんでgetterなのにコメントだと行数が増えてるんだ？
このメソッドは1オリジンの場合の行数を取得したいだけで、行数の変更なんてしていないはずだぞ？
もともとのコメントでは「カウント」だったわけだが、脳内補完すれば「行数」になるはずだ。

……まぁ、要するに、今度こそ誤訳が顔を出してきたわけだ。1行ずつ確認していこう。
```php
$count = $this->rowCount; // 行数を取得
```
特におかしなことはない。行数を取得してるだけだし。
```php
$count = $count + 1; // 行数を1増やす
```
問題はココだ。行数が増えてしまった。
コードにそんな副作用はない。しかし、コメントが正しいならここで行数が増えているのだ。
直訳しただけのはずなのに、何故こうなってしまったのか？

### 誤訳の正体
もったいぶってもしょうがないのでサクッと行こう。
```php
$count = $count + 1; // 行数を1増やす
```
ここが誤訳ということになるのだが、それはなぜか。
答えは「**左辺の`$count`と右辺の`$count`は意味が違うから**」である。

左辺の`$count`は**1オリジンでの行数**で、右辺の`$count`は**0オリジンでの行数**だ。
つまり、このコードは`$count++`とは違う概念であり、故にインクリメントと同じコメントでは誤訳になってしまうのだ。

# 結論。または、「じゃあ、どうすべきなのか？」
```php
$count = $count + 1; // カウントを1増やす

$count = $count + 1; // 行数を1増やす
```
直訳コメントが良くないというのなら、どうすべきなのか？コメントしないのが正解なのか？
今回の例で言えば、**コメントしないのがベストかといえばNo**だろう。
ただし、先の例のような**直訳コメントを書くくらいなら、コメントしない方がベターである**だろう。
では、コメントするならどのようにするべきだったのか。

## するべきだったコメント
今回の例の場合、両辺の`$count`の違いを意識すれば「1増やす」ではなく「変換」が目的であることが分かる。
これがコード上から読み取りづらかったわけで、そこを補完できるようコメントしてやれば良い。
よって、コメントすべきだったのは下記のようなものである。
```php
$count = $count + 1; // $countを0オリジンから1オリジンに変換
```
もはやどうみても直訳ではない。ついでに言えば`$count`は訳さずベタ書きだ。
しかし、「この行は何をしたいのか」という情報が記載できている。
もちろん、行数が増えるなんてこともない。

# 処方箋という名のおまけ
**そうは言っても、上手く書けないからこうなってるんじゃい！**

まぁそりゃそうだ。誰だってわざと下手なコメントをしてるわけじゃない。多分。
いい感じのコメントを書くにはどうすればいいのか？極論は「練習して慣れる」になるが、その前にできることがある。

## コードから治す
```php
public function getOneBasedRowCount()
{
    $count = $this->rowCount;
    $count = $count + 1;
    return $count;
}
```
さて、もう一度こいつを例にするとして。まずはコメントなしの状態。
ここにコメントを付ける……前に、コードを変えてしまおう。コメントしづらさは結構な率でコードのせいだ。
```php
public function getOneBasedRowCount()
{
    $zeroBasedCount = $this->rowCount;
    $oneBasedCount = $zeroBasedCount + 1;
    return $oneBasedCount;
}
```
`$count`の使い回しをやめて変数名で0オリジン1オリジンを明示した。
この時点で`$count++`との混同は起きづらくなっただろう。
※今回使ってる例のコードはPHPなのでimmutable的な話は省略するが、JavaScript的に言えば「letやめてconstにしよう」C++的に言えば「とにかくconst付けろ」と言った具合である。
```php
public function getOneBasedRowCount()
{
    $zeroBasedCount = $this->rowCount; // 0オリジンの行数を取得
    $oneBasedCount = $zeroBasedCount + 1; // ここのコメントをどうするか
    return $oneBasedCount;
}
```
さて、使い回しをやめて変数名を変えただけなので形は大きく変わってない。
では、問題のコメント部分をどうすればいいのか。

実は、`$count`の使い回しをやめたことで使えるようになった簡単な方法がある。
それは「{右辺の主役}を{左辺のあるべき形}に変換する」とすることだ。
```php
public function getOneBasedRowCount()
{
    $zeroBasedCount = $this->rowCount; // 0オリジンの行数を取得
    $oneBasedCount = $zeroBasedCount + 1; // 0オリジンの行数を1オリジンの行数に変換する
    return $oneBasedCount;
}
```
これで完成だ。少々仰々しいが、誤訳の危険は大いに減っただろう。

ただし、そもそもこの方法は「いやもうコメントなくてもそのまま読めるじゃん」となることもある。
そうなったならば、そのコメントはもはや要らないものかもしれない。
サクサクと消していきたいかも知れないが、慣れないうちは先輩などに相談してからにしよう。
変数名で頑張るよりコメントにしたほうが読みやすいことも少なくはないのだ。