こんにちは、hachi8833です。前回の命名編に続き、今回のコメント編も英語圏に寄った指示が多く見受けられます。
このセクションで興味深いのは、「コメントを増やすよりコードを改善せよ」というメッセージ自体が繰り返し主張されていることです。
こうした指示は、本来であればそれこそスタイルに1行書いて簡潔に終わらせたいところだと想像できますが、どれほど口を酸っぱくして指示しても、結局多くの人が残念なコメント記法を使ってしまっているということなのでしょう。
コメント(comment)
よく書けたコードは、それ自体が最も優れたドキュメントになる。コメントを追加する前に、もう一度自問して欲しい: 「このコメントを足さなくてもいいようにコードを改良できないだろうか?」ひと手間かけてコードを改良してからドキュメントを書けば、単なるコメント追加よりずっと明確になるはずだ。
-- Steve McConnell
4-01【統一】コード自身に語らせろ(コメントは最小限に)
Write self-documenting code and ignore the rest of this section. Seriously!
「コメント編についてはこれさえやってくれれば、ここから先はもう読まなくたっていい(マジでマジで)」とあるぐらいなので、ダメなコメントがどれほど多いかを実感できますね。
追伸: ないと困るコメントについて
不要なコメントを削ることに夢中になるあまり、必要なコメントまで削ってしまわないようにしたいです。
以下のようなコメントはないと困るorあると喜ばれるコメントです。
- ロジックだけではわからないコーディングの背景や理由(特に黒魔術系)
- 参考にしたURL(モンキーパッチなどを流用した場合など)
「ダメなコードを言い訳するコメント」でなければ、そのコメントはもしかすると必要かもしれません。
コードをクイズにしてしまわないための、読む人にやさしい的確なコメントを心がけたいと思います。
4-02【統一】コメントは英語(≒自国語)で書くこと
Write comments in English.
どよめきが聞こえてきそうな指示ですが、日本語圏であれば「自国語で書く」と理解してよいと思います(学校の教科である「国語」を米国ではEnglishと呼んでいるのと同じですね)。
以下いくつか英文法に寄った指示がありますが、日本語に合わないところは適宜解釈するとよいでしょう。
4-03【統一】コメント記号#
とコメント記号の間は1スペース開けること
Use one space between the leading # character of the comment and the text of the comment.
これは美観上の理由で統一したと思います。私自身、#
の後ろにスペースがないと窮屈な印象を受けます。
4-04【統一】1語より長いコメント文は冒頭を大文字にし、句読点を省略せず、ピリオドの後にスペースをひとつ置く
Comments longer than a word are capitalized and use punctuation. Use one space after periods.
2語以上のコメントは文として扱うようにという指示です。
上の2つは、コーディングというよりも英文のスタイルの統一ですね。英文ドキュメントにも文法とは別にスタイルというものがあり、スタイルは出版社やコミュニティによって異なります。
「箇条書きの最後にピリオドを置くかどうか」「見出しの単語をすべて大文字にするかどうか」などは英文法ではなく、英語のスタイルの範疇です。文法とスタイルは分野を問わずごっちゃにされやすい傾向があります。
4-05【統一】無駄なコメントは削ぎ落とすこと
Avoid superfluous comments.
# 不可
counter += 1 # counterに1足す
学校の授業のコードサンプルでは説明のためにこういう冗長なコメントが大量に使われることがよくありますが、もしかすると英語圏ではそれを真に受けてずっとやり続けている人が割りといるのかもしれません。英語圏に限りませんが。
4-06【統一】コメントを古いままにしないこと
Keep existing comments up-to-date. An outdated comment is worse than no comment at all.
「コメントを更新しないのは、コメントがないよりもずっとたちが悪い」とのことです。
4-07【統一】ダメなコードをカバーしようとするコメントを書くな
Avoid writing comments to explain bad code. Refactor the code to make it self-explanatory. ("Do or do not—there is no try." Yoda)
これも「心がけ」の範疇ですね。抽象度の高いコードでは逆にコメントがないとクイズになってしまうかもしれません。
おまけ
「Do or do not—there is no try.」は、ヨーダ記法という用語の元にもなったヨーダの名言からの引用です。
この発音には東洋人訛りを意図的に混入させていると思われますが、私の聞き取り能力ではそこまで区別できません(´・ω・`)。「主人公を導く、途方もない力を持つ謎の老師」は東洋人へのステロタイプのひとつです。
アノテーション(annotation)
※当初の「注釈」を「アノテーション」に改めました。
いわゆるcommentとは別にannotationについて言及されています。
- comment: 特定の大文字キーワードで始まっていないフリースタイル(本記事では「コメント」)
- annotation: 大文字のキーワードで始まり、commentよりも形式が定まっている(本記事では「アノテーション」)
アノテーションの大文字キーワードはIDEやコード解析ツールでもサポートされていることがありますので、効果的に利用しましょう。
def bar
# FIXME: ←「大文字キーワード+コロン+スペース」はコメント中でもハイライトされる(FIXME: ←冒頭以外でも有効)
baz(:quux)
end
よく書けたコードは、うまいジョークと似ている: どちらも説明すればするほど野暮になる
— Russ Olsenが伝えた、ある古参プログラマの金言
4-08【統一】アノテーションは、説明したいコードのすぐ上に書くこと
Annotations should usually be written on the line immediately above the relevant code.
アノテーションを離れたところに書くと不便なだけなので、これはもっともですね。
もうひとつの意図は、アノテーションをコードの上に置いたり下に置いたりというばらつきをなくしたい、ということだと思われます。
4-09【統一】アノテーションは、最初にキーワード、次にコロンとスペースを置き、それから問題を記述すること
The annotation keyword is followed by a colon and a space, then a note describing the problem.
上述のとおりです。
4-10【統一】1行に収まりきれない場合は、2行目以降の#
以降のスペースを3文字増やす
If multiple lines are required to describe the problem, subsequent lines should be indented three spaces after the # (one general plus two for indentation purpose).
スペースを3文字増やすことで、最初の1スペースと合わせてRubyのインデント2つ分になり、他とインデントが調和します。
def bar
# FIXME: v3.2.1以降たまにクラッシュする
# BarBazUtilのアップグレードが関連している疑いあり
baz(:quux)
end
4-10a【例外】問題点が自明なら、該当箇所の後ろにキーワードだけのアノテーションをつけてもよい
In cases where the problem is so obvious that any documentation would be redundant, annotations may be left at the end of the offending line with no note. This usage should be the exception and not the rule.
def bar
sleep 100 # OPTIMIZE
end
4-11【統一】アノテーションのキーワードには以下を使う
- TODO
- 後日追加が必要な、不足の機能
- FIXME
- 修正の必要な箇所
- OPTIMIZE
- パフォーマンス低下の原因となる箇所
- HACK
- リファクタリングの必要なマズいコード
- REVIEW
- 意図したとおりに動くかどうかチェックが必要
↓REVIEWの例です。
# REVIEW: 顧客は本当にXを行っているのか?
- その他
- 必要ならキーワードを足してもよいが、READMEでキーワードを説明すること
- Use TODO to note missing features or functionality that should be added at a later date.
- Use FIXME to note broken code that needs to be fixed.
- Use OPTIMIZE to note slow or inefficient code that may cause performance problems.
- Use HACK to note code smells where questionable coding practices were used and should be refactored away.
- Use REVIEW to note anything that should be looked at to confirm it is working as intended.
For example:REVIEW: Are we sure this is how the client does X currently?
- Use other custom annotation keywords if it feels appropriate, but be sure to document them in your project's README or similar.
追伸
TechRachoで使っているhighlightjsでは、TODOとFIXMEのみが強調されました。
def bar
sleep 100 # TODO:
sleep 100 # FIXME:
sleep 100 # OPTIMIZE:
sleep 100 # HACK:
sleep 100 # REVIEW:
end
GitHubのシンタックスハイライトにはこの強調表示はないようです。
マジックコメント
Rubyのマジックコメント(magic comment)は、スクリプトエンコーディングを明示的に指定する場合に使います。エディタでのエンコーディングを独自に指定したり、外部のスクリプトで使う設定を書くのに使われることもあります。
Ruby 2.0以降では、スクリプトエンコーディングが指定されていない場合のデフォルトはUTF-8になります。
以下はマジックコメントの例です(すべて#
で始まります)。
# coding: euc-jp
# encoding: euc-jp
# -*- coding: euc-jp -*-
# vim:set fileencoding=euc-jp:
# frozen_string_literal: true
4-12【統一】マジックコメントはすべて最上部に置くこと
Place magic comments above all code and documentation. Magic comments should only go below shebangs if they are needed in your source file.
いわゆるshebang(シェバン)は、#!/usr/bin/env ruby
などのように、Ruby実行環境のパスをシェルに伝えるためのコメントです。
例外として、shebangはマジックコメントよりもさらに上(最初の行)に置く必要があります。
# 不可
# Personの説明
# frozen_string_literal: true # FIXME: マジックコメントはドキュメントより上にすること
class Person
end
# 良好
# frozen_string_literal: true
# Personの説明
class Person
end
# 不可
# frozen_string_literal: true
#!/usr/bin/env ruby # FIXME: shebangは最上部に置くこと
App.parse(ARGV)
# 良好
#!/usr/bin/env ruby
# frozen_string_literal: true
App.parse(ARGV)
- 参考: Wikipedia: シバン
4-13【統一】1行に複数のマジックコメントを書かない
Use one magic comment per line if you need multiple.
# 不可: マジックコメントが複数書かれている
# -*- frozen_string_literal: true; encoding: ascii-8bit -*-
# 良好
# frozen_string_literal: true
# encoding: ascii-8bit
4-14【統一】マジックコメントと他の部分との間には空行を1つ置く
Separate magic comments from code and documentation with a blank line.
# 不可
# frozen_string_literal: true # FIXME: 下に空行が必要
# Personの説明
class Person
# Some code
end
# 良好
# frozen_string_literal: true
# Personの説明
class Person
# Some code
end
関連記事
- Rubyスタイルガイドを読む: ソースコードレイアウト(1)エンコード、クラス定義、スペース
- Rubyスタイルガイドを読む: ソースコードレイアウト(2)インデント、記号
- Rubyスタイルガイドを読む: 文法(1)メソッド定義、引数、多重代入
- Rubyスタイルガイドを読む: 文法(2)アンダースコア、多重代入、三項演算子、if/unless
- Rubyスタイルガイドを読む: 文法(3)演算子とif/unless
- Rubyスタイルガイドを読む: 文法(4)ループ
- Rubyスタイルガイドを読む: 文法(5)ブロック、proc
- Rubyスタイルガイドを読む: 文法(6)演算子など
- Rubyスタイルガイドを読む: 文法(7)lambda、標準入出力など
- Rubyスタイルガイドを読む: 文法(8)配列や論理値など
- Rubyスタイルガイドを読む: 命名
- Rubyスタイルガイドを読む: コメント、アノテーション、マジックコメント
- Rubyスタイルガイドを読む: クラスとモジュール(1)構造
- Rubyスタイルガイドを読む: クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど
- Rubyスタイルガイドを読む: クラスとモジュール(3)クラスメソッド、スコープ、エイリアスなど
- Rubyスタイルガイドを読む: 例外処理
- Rubyスタイルガイドを読む: コレクション(Array、Hash、Setなど)
- Rubyスタイルガイドを読む: 数値、文字列、日時(日付・時刻・時間)
- Rubyスタイルガイドを読む: 正規表現、%リテラル、メタプログラミング(最終回)