いつコメントを書くべきかのガイドライン
「どういうコメントを書くべきではないのか」についてはなんかまぁ色々あるよう(大人の表現)ですが、僕は基本的に「迷ったら書けよ」という方針なのでそういう立場からコメントの書き方の指針みたいなものをまとめておこうかなと思いました。
なお、ここではなるべくシンプルにまとめたいので
n = raw_input() # 入力してもらう名前 # もし名前が20文字以上だったら馬鹿にする if len(n) >= 20: return 'お前の名前長過ぎワロタ'
とか、その手の無意味なコメントは害悪だという前提を共有出来ているとしてまとめています。
どうして上のような説明コメントが悪いのかわからない場合は プログラミング コメント 悪い
みたいなキーワードでググるとそれっぽい文章がヒットすると思うので、それを先に読むといい感じになるとおもいます。
また、動けば良いやなぐちゃぐちゃコードにコメントを入れるのも当然NGです。あくまでコードが主、コメントは従です。
迷ったらいれる
「コメントを書いた方が良いかなぁ」と少しでも迷うということは、それはコードが難解になりつつあるというサインなのでコメントを書くべきです。
「コメントを書く暇があるなら読みやすいコードにしろよ」という意見はもっともですが、様々な要因*1からそう出来ない場合もありますし、そもそもの要求が複雑だったりすることもあるわけです。
個人的には、ソースコードは書くよりも後から消す方が難しいと感じているわけですが、コメントに関して言えば後から書くよりも書いてあるものを消す方が簡単なんじゃないかと思っています。
もしも後になってやっぱこのコメントは冗長だなと思ったら消せば良いだけですし、コメントがあって良かったなぁって思ったらめでたしめでたしなのでとりあえず書けば良いと思います。
以降についても、とにかく必要っぽかったら書いておいて、いらねえと思ったら後から消せば良いじゃんの原則が根底にあるとおもってください。
ロジックが複雑なところにも入れる
コードをシンプルにするのが先ですが、前述したように納期だとか、気力だとか、能力だとかの限界みたいな都合でそれが出来ない場合というのはどうしても生じます。
そういう部分には、そこの塊が何をしている、したいかの説明を入れるようにしましょう。ミニミニ仕様書みたいなもんです。
何をしたいのかさえ明確に書いてあれば、余裕がある時の自分やスーパーハカーの人がきた時に実装し直すのも簡単です。
また、そういう部分にはTODO:
や、強く修正の意思がある場合はFIXME:
などのプレフィックスを付けておくと良いでしょう。
多くのエディタ、IDE、またRuby on Railsなどのフレームワークはそれらのプレフィックス付きコメントに対するサポート機能*2を備えています。
FIXME
に関しては、既知のバグがある場合などにも利用されます。
プレフィックスを付ける基準については bbatsov/ruby-style-guide · GitHub などの属しているコミュニティのものを参考に、チームで合意をとって統一すると幸せになるとおもいます。
何かしら着想を得た元の実装が存在する
コピペは論外ですが、何か元ネタ的になった実装や、書き方の詳細な説明があることは往々にしてあるようにおもいます。そういった実装に関しては、元の実装に対するリンクや書籍名などを入れておくと読み手の理解の助けになるだろうと思います。
外から使われるメソッドや関数にはとりあえず入れる
PythonやClojureだとdocstringという形で使う時に参照出来ますし、VisualStudioなどのIDEも補完の時にコメントを参照する機能を持っていることが多いです。
もちろん、関数名だけで全てが説明されきっているのが理想ですが、現実はそうではないので、特に広く使われるような重要度の高い関数などは使用例などを含めた丁寧なコメントを入れるに越したことはないでしょう。
ただのゲッターセッターのようなものにまで入れる必要はないとはおもいますが。
返却するオブジェクトに対する説明、あるいはアノテーション
必ず返り値の型を明示しないといけない言語では不要ですが、動的型の言語や、型推論が強力な言語の場合は書かなくても良い、省略出来ることがあります。
静的型の場合は省略したほうがカッコいい感じがしますし、コードもすっきりしたような雰囲気はするわけですが、特に理由がない限りはプロトコルなりでもなんでも良いですが、振る舞いを明示しておいてくれたほうが嬉しい感じがします。
筆者はパワフルな静的型の言語の経験が浅いのでここら辺は間違ってるかもしれません。でもHaxeを書いててめんどくせえなと思ったりすることが何回かあったんで、出来れば書いててほしいですね。
動的型の場合、全部の場所にいちいち書き込んでいたら「ダックタイピングはどうしたんだ!」みたいなことを言われてしまうわけなんですけども、例えばJavaScriptなんかはどんどん静的型付けワールドが支配的になりつつあるわけです。
実際、アノテーション的なものを付けることでツールやIDEによる補完や解析の援護を受けれるようになって便利感が大きくなります。Google Closure Compilerとか、Flow.jsとかなんか色々ありますね。Pythonだとjediとかがあります。
実際、コメントなんかに「この関数は○○○を返します!」みたいなことが書いてあっても「なるほどナー。でもこのオブジェクトがどういうメソッド持ってるかわからないなー」みたいなことになって、結局試しに走らせたりコードを追ったりしないといけないのがクソめんどくさいと思います。
例えばPythonやRubyなんかでも、返り値の型を明示したところで何かが損なわれるようなことはない(ダサい感じがして精神的には何かが減る可能性はある)ので、パブリックな役割を持つ関数なんかは返り値の型を書いておいていいんじゃないの? と思います。補完も効くようになるし。
「型を明示してたら動的型のメリットが減るだろ!」みたいな意見はわからなくもないんですが、そもそも型表記をサボれるっていうのは動的型付き言語の存在意義では全くないです。なので、ダックタイプ的な振る舞いをベースにおいたプログラミングをする上で、返り値の振る舞いについてコメントするのに型を書くのが結局一番簡潔でわかりやすいんじゃないかな? っていう判断によってこの主張をしています。
訳あって泥臭い実装になっているところには絶対入れる
僕のような傲慢な人間は、テンションが高い時に実装が泥臭いところをみかけると「オイオイオイなんだよダサい実装だな! 俺がカッコ良くしてあげるぜ」みたいなことを思って書き直したりすることが稀になくはないわけですが、実はそれが特定の環境やバージョンに対応するための苦肉の策だった……みたいなことが起きたりします。
良かれと思った修正によってテストがこける、バグが再発する、みたいな無駄作業の悲しみを生まない為にも、そういう自分の苦労の跡にはコメントを入れておくと良いでしょう。
コミットコメントに入れておくだけでも良いとは思うんですけども、その度にいちいちblameするかっていう話ですし、重要度が高いものはソースコードに含めちゃった方がよくねという立場です。
こちらも、場合によってはコメントにプレフィックスを付けると良いでしょう。
苦肉の策的な怪しい実装に対してはHACK:
、ボトルネックになりそうな遅い実装に対してはOPTIMIZE:
などがあるようです。
技巧的なコーディングをする時にはなるべく入れる
「コメントを読む相手は自分と同じ技量の人間だと思って書け」とはいいますが、例えばメタプログラミングなどの難解な記述は、どうしても難易度が高くなりがちですし、読み書き出来る人間の数も減るわけなのでコメントを入れておいて損はないんじゃないかなーとおもいます。後からくる人への学習の指針にもなるとおもいますし。
但し、文章量が膨大になるようであればコメントではなくドキュメントの整備が必要になるかもしれません。
理想は極力そういった難解なコードは書かずに、サードパーティなどに役割を押し付けてしまうことではないかなと思いますが。
まとめ
こんな感じで、個人的にコメントを入れるべきだよなと感じているタイミングについて書きました。
世の中には「こういうコメントを書くべきではない!」みたいなエントリの方が多い気がします。
恐らくそれには理由があるのだと思います。その一つは「コメントは一種の警告である」ということです。警告なので、あまりにも頻繁に行うと狼少年になってしまい誰も注意を払わない、ただのノイズになってしまいます。つまり、無駄なコメントを極力減らすという努力は、間接的に他のコメントの価値を向上させる行為につながるわけです。
なので、本エントリでは「とりあえず沢山書いておけばいいっしょ!」みたいな書き方はしていますが、あくまでソースコードが主でコメントが従であり、またコードもコメントも量より質だということを念頭に置いておく必要はあるはずです。
沢山書いておけば良いっしょっていうのは、あくまでコメントは後からの修正が楽だからという観点に基づくものなので、沢山書きまくって放置するみたいなのは論外です。ソースコードもコメントも、共に大事な保守の対象です。
ソースの質というのは、プログラマーのコミュ力そのものみたいなもんだと僕はおもっているので向上させ続けたいですね。
いじょうです。