プログラミングスタイルガイドのスタイルガイド

  • 881
    Like
  • 0
    Comment
More than 1 year has passed since last update.

本文書は、プログラミング言語向けのスタイルガイドに向けたスタイルガイドである。

構造

対象を明確にする

そのスタイルガイドがどのような状況のどのような対象に向けたスタイルガイドであるか規定すること。
状況や対象は広すぎてはならない。

理由:

  • 対象はスタイルガイド記述者には自明かもしれないが、似て非なる言語に誤用されたり、特定分野のアプリケーション向けスタイルガイドが他分野のアプリケーションを理不尽に拘束したりすることがある。これを防ぐべきである。

良い例:

  • 「本文書はRuby on Railsアプリケーション向けのスタイルガイドである」
  • 「本スタイルガイドはX社におけるRubyプロジェクトに適用すべきスタイルを規定する」

悪い例:

  • (何も書かない)
  • 「本文書はX社におけるすべての開発に適用される ... 述語メソッドや述語関数名は"?"で終わること」
    • この名前はRubyには適切かもしれないが、Pythonに適用されたら途方に暮れるだろう。

関連項目:

  • 理由を書く, 例外: スタイルガイド全体の適用範囲が本ルールにより示される一方、個々のルールの適用範囲は理由や例外により明確化される

構造を与える

ランダムに「○○せよ」「○○するな」と列挙するのではなく、構造を与えること。

理由: スタイルガイドはランダムな知識の集合ではなく、プログラムに良い構造と一貫性を与える。それはコードレビューの際などに繰り返し参照され、状況の変化や新たな発見に応じて更新され、それでも一貫性を保たねばならない。
参照時に適切なルールを素早く見つけ、矛盾なく更新するためには構造が必要である。

良い例:

  • デザイン
    • クラス
      • クラスのサイズ
      • 多重継承
    • メソッド
      • 宣言的スタイル
      • コマンドクエリ分離
    • ...
  • フォーマット
    • 識別子
      • クラス名
      • メソッド名
      • 定数名
      • 変数名
    • 順序
      • import文の順序
      • クラスメンバーの順序
    • 空白の扱い
      • ...

悪い例:

  • ○○するな
  • △しろ
  • ××するな
  • ...

デザインを規定する

システムやモジュール、ライブラリの良いデザインや習慣を規定し、デザイン上のありがちな間違いを戒めること。

理由: ソースコードの字面上の一貫性と健全性だけでなく、コードによって実現されるデザインの一貫性と健全性もまたシステムを読み取りやすく維持しやすくするために重要である。

良い例:

メソッドは簡潔に、1つの責務に注力するようにすること。40行を越える場合は適切に分割できないか検討すること。

例外: デザインの指針を規定する「Effective XXX」のような文書が別途存在するかもしれない。その場合は単にその文書を指し示すだけで足りるかもしれない。

フォーマットを規定する

ソースコードの字面に対して、一貫していて健全なフォーマットを規定すること。

理由:

  1. 構文上正しくとも読みづらいコードはいくらでもあり得るため、どうすれば読みやすくなるのかという暗黙知を明文化することで開発者たちを助ける
  2. ソースコード内でスタイルが一貫していないと一目で全体を把握するのに差し支える一方、どのスタイルが好みであるかは見解が分かれがちである。 そのため、どのスタイルを取るべきか事前に決めておく必要がある。

良い例:

一行の長さは極端に長くしないこと。120文字を越える場合は分割した方が読みやすくないか検討すること

例外: goのような一部の言語ではフォーマット上のほとんどの問題は標準の自動整形器が処理してくれる。この場合は単にその整形器を使うよう規定するだけで良いかもしれない。

理由を書く

そのルールを導入することでもたらしたい利益や、防ぎたい問題、背景状況を記述すること

理由:

  1. 防ぎたい問題が書かれていれば、問題がなくなった際やよりよい解決策が見つかったときにはルールを改定できる
  2. そのルールを適用すべき範囲の境界をより適切に判断する助けとなる。杓子定規にルールを適用するのを防止できる

良い例:

  • (古いJavaのスタイルガイドで) 「3つ以上の要素を結合して文字列を構築する際には常にStringBufferを利用する。 (理由: パフォーマンス)」
    • → 理由が書かれているので、新しいバージョンのJavaではStringBuilderを利用しても良いことや、javacが自動的に対応してくれる場合は+で結合して構わないことを判断できる。

悪い例: (Cのスタイルガイドで)「条件演算子は使ってはならない」

例外: フォーマットのルールなど、一部のルールには大した理由はない。どのやり方でも良いが、とにかく一貫性のためにどれか1つを規定すべきだっただけである。この場合には無理に理由をひねり出すべきでない。

関連項目:

  • 対象を明確にする: 個々のルールの適用範囲のみならず、スタイルガイドそのものの範囲も別途記述される。
  • 例外: 明示的な例外規定は適用範囲をより明確にする

良い例と悪い例

各々のルールには例を示すことが望ましい(SHOULD)。良い例と悪い例の両方を示すと更に良い。

理由: ルールの本文はあるべき実装のあり方を内包的に示す。例はそれを外延的に示す。両者が揃うことで読者はルールをより正確に理解できるようになる。

良い例:

  • (Rubyのスタイルガイドで)

定数名にはSCREAMING_SNAKE_CASEを用いる。

  • 良い例: 「EXAMPLE」「EXAMPLE_CONSTANT
  • 悪い例: 「Example」「ExampleConstant」「Example_Constant

例外:

  • 存在を規定する「○○があること」というルールは適切な悪い例がない場合もある。
  • 不在を規定する「○○がないこと」というルールに適切な良い例がない場合もある。

例外

ルールが適用不能な例外ケースを明示する

理由: 多くの場合に推奨されるべきルールであっても特定の状況では不適当なことが良くある。この場合にスタイルガイド利用者が杓子定規にルールを適用して却って可読性や保守性を損なうのを防ぐ必要がある。

例外: 一部のルールは本当に常に適用されるべきで有り、例外を持たないかもしれない

良い例:

  • (Cのスタイルガイドで) 「極端に短い識別子は避けること。 例外: ループを制御するインデックス変数には短いi, j, kなどを用いるべきである」
  • (Rubyのスタイルガイドで) 「特殊変数は極力利用を避けること。例外: ワンライナーやコードゴルフ」

関連文書:

  • マーフィーの法則: 例外の法則

慣習を記述する

慣習上自明なことも記述すること

理由: 誰にとっても自明とは限らない

良い例:

  • (C向けスタイルガイドで)「ループ用のインデックスには冗長な名前を避け、i, j, kを順に用いるのが望ましい(SHOULD)」

文法を再記述しない

プログラミング言語の文法で規定されていることを再記述しない。

理由: 無駄で邪魔なため。処理系が検出してくれる文法を改めて規定する必要はない。

良い例: (Rubyのスタイルガイドで)「識別子にはASCII印字可能文字のみを用いる」
悪い例: (Rubyのスタイルガイドで)「クラス名は大文字で開始すること」
例外: 処理系の実装依存な文法の利用を制限したり文法上曖昧な点を明確にするのは意味がある

悪しき遺産を排除する

多くの言語は、歴史的経緯や初期の間違った設計により導入された使うべきでない機能を持っている。このような機能の利用を戒めること。

理由: これらは確かに機能はするので、明確に禁止しない限り誰かが使うだろう。

良い例:

  • (Rubyのスタイルガイドで) 「$,に依存せず、Array#joinなどには区切り文字を明示すること」
  • (Javaのスタイルガイドで) 「マーカーインターフェースではなくアノテーションを利用すること」

悪い例:

  • (何も書かない)

関連項目:

  • 理由を書く: 機能するのになぜ禁止されているのか明示しないと、誰かがルールを破ることになる

関連項目/関連文書

スタイルガイド中のルールが他のルールや外部文書と関連する場合はそれらを示すこと。

理由:

  • 補完し合うルールや文書を提供することで読者がより深い理解に至る助けとなる
  • 一部のルールは互いに競合し、読者はそれらの間の適切なバランスを探る必要がある。このとき、まず読者は競合関係の存在を知る必要がある。

フォーマット

メタ変数/例示定数

ルール中のメタ変数または例示定数値からは極力文脈依存を排除すべきである。特に意味のない一般例であることが明確に分かることが望ましい(SHOULD)。

慣習または標準規格により例示用の名前が規定されている場合はそれに従うこと。

理由: 例示された変数や定数値が意味ありげだと、その名前/値である必然性があるかのように見えて読者を混乱させる。

良い例:

  • x
  • example
  • foo
  • hoge (日本語話者に向ける場合のみ)
  • foo@domain.example (ドメイン名)
  • 192.0.2.1 (IPv4アドレス)
  • spam (Pythonのみ)

悪い例:

  • __system_shutdown_handler__
  • RubyVM::jit_enabled?

関連項目:

  • RFC 2606
  • RFC 3092
  • RFC 5737
  • ユーモア: 意味のない名前とユーモアの両立は難しいので、よいバランスを探る必要がある

制約度合い

ルールの強制力の強さを明確にすること。RFC 2119に倣うのが望ましい(SHOULD)。

理由: 一部のルールは包括的な例外リストを与えるよりは読者に適否判断を委ねた方が良い。そのようなルールを厳格に守るべきルールと区別するためである。

目次

スタイルガイドの先頭には目次があることが望ましい(SHOULD)

理由: スタイルガイドは繰り返し参照されるため、うろ覚えの読者が素早く目的の項目に到達できるようにする必要がある。

URI

スタイルガイドの各ルールはURIを持つべきである。

理由: コードレビューの議論において特定のルールを指し示す必要があるため、URIが必要となる。

良い例:

  • https://example.com/styleguides/whitespace#rule-01-comment
  • doi:10.1000/xyz123-201508250102030001
  • urn:uuid:BCE05860-F8CB-4B97-9FF5-B2E2F873CFE0

そこそこ良い例:

  • [Ruby0001]

関連項目:

短い見出し

各ルールは記述的な短い見出しを持つことが望ましい(SHOULD)

理由: URIはルールを一意に示すには有用だが、人間が一目見て理解したり口頭で用いるには不適なことがある。その場合は各ルールが簡潔な見出しを持っていると補える。

良い例:

  • 「インデント」
  • 「メンバーの宣言順序」

悪い例:

  • (見出しがない)
  • 「RULE A8310D71」(記述的でないため覚えられない)

ユーモア

規定にはユーモアを交えることが望ましい(SHOULD)

理由: スタイルガイドはともすれば無味乾燥で拘束的な文面になりがちである一方、よりよい開発には創造性とそれを支える自由が必要であり、両者は対立する。この緊張関係を解決するにはユーモアがあると良い。
良い例: 無茶言うな
例外: ユーモアのセンスがない場合は仕方がない