クボブログ

https://toiro-skin.com

リーダブルコード(1/3)『命名』

 

今回はバイトで読むように言われた本がだいぶ面白かったのでその内容を要点だけまとめて、自分が忘れないようにしようというものです。

 

はい、いわゆる「備忘録」っていうやつです。

 

で、その本はこれです。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

 

内容はだいぶ省略するので本気で読みやすいコードを書くのが仕事とかで必要な人はこのブログじゃなくて上の本を買うことを強くお勧めします。

 

というより、本のまるまる内容をここに乗せたら犯罪触れそうなんで。

 

ということで今回の内容「命名」です。

上の本ではちょうど「2章」「3章」の内容ですね。

 

まぁ、さすがに「hensu」とか「fun1」みたいな適当過ぎる名前使うのは本当に論外なので今回は省きます。

 

 

 

良い名前とは?

 

良い名前をつける方法の前にどのようなものが良い名前なのかということについて自分の認識について語っていこうと思います。

 

結論としては

コメントアウトのような名前

ということだと思います。

 

わかりやすく言うと「名前をみるだけで何をする処理(数)なのかということがわかるもの」ということです。

だから、名前だからと言って適当に命名するのではなく、より内容を具体的に示せるように必要な情報をたくさん詰め込むことが重要なのです。

 

要点1:標準の命名規則に従う

命名規則とは、コードを書く時の変数や関数名の付け方などのルールです。

ネーミング規則やネーミング規約、命名規約などとも呼ばれています。

命名規則に従ってコードを書くことで、一定のその規則に従うことでその名前が意味する処理内容(変数)などの意味を読み取ることが容易です。

こういうのはプロジェクトで固有に決めるよりも世の中に共通認識として出回っているものを使うことが推奨されています。なぜなら、一緒に何らかの作業をするプロジェクトメンバーは常に同じ人とは限らないからです。

もし、プロジェクトに新しい仲間が増えたときにソースコードがローカルルールに沿って書かれていた場合、パッと見で理解することはできないでしょう。

また、それは外部の人にソースコードを見せる場合も同様です。

 

それでは、標準の命名規則に従う場合はどうなるかというと、その命名規則を知っているひとは一定数いるわけです。少なくとも、ソースコードを見せる相手はすくなくともその道の人たちが多いわけなので通じることは比較的多いはずです。

そういう標準の命名規則は言語ごとにあたりなかったりしますが大体は一緒です。

だから「言語名 _ 命名規則」的な感じでググればわかります。

とりあえず、下には「C++」と「Python」の命名規則のリンクを貼っときます。

qiita.com

 

はじめに — pep8-ja 1.0 ドキュメント

 

 

このように、命名規則はコードの一貫性に関するものです。

プロジェクト内で一貫性を保つことは重要ですが、一貫性を崩すべき場合もあります。

命名規則を無視する正当な理由は以下の通りです。

1.命名規則に従うとコードが読みにくくなる場合。

2.命名規則に従っていない周囲のコードとの一貫性を保つ場合。

(しかし、これは誰かの汚いコードをきれいにするチャンスでもあります)

3.既存のコードが命名規則を準拠していない以外に問題がない場合。

4.命名規則で推奨されている機能をサポートしていないバージョンの互換性を保つ必要がある場合。

5.命名規則に従うとコードの後方互換性が保たれない場合。

後方互換性:古いシステムに対して新しいシステムが持っている互換性。

 

要点2:ローカルルールも用意しよう

これは上の標準の命名規則と同じような内容なので説明は軽くなります。

これは、上の命名規則に付け加える形の「ローカルルール」を用意すべきということです。

標準の命名規則はプログラムの細かい部分までを束縛するようなことはしません。

だからと言って好き勝手名前を付けていいわけではないです。

そのプロジェクトが任意で意思決定ができる範囲に一貫性を持たせることでより良いコードになります。

例えば、関数の名前を「動詞 + _ + 目的語」の形に統一することで誰から見てもわかりやすい内容になります。

また、単語にルールを決めても良いでしょう。

機能 名前
値を代入する set...
値を取得する get...
計算する calculate...
変換する convert...to...
真偽値を返す is...

 

のような感じに単語ごとにその名前の関数やクラスなどの機能をあらかじめ決めておくことでどのような処理を行うということが明確になります。

他にも時間やバイト数のように計測できるものであれば変数に単位を入れたり、危険や注意を喚起する情報を追加したりしたら良いでしょう。 

 

要点3:複数の動作が想定される名前は避ける

では早速わかりやすい名前を使う上で押さえておきたいことについて説明していきます。

例として「check」をあげてみましょう。

プログラミング界隈では、この単語は『何らかも確認』と言う意味で使われることが多いです。

ですが、この単語では意味が広すぎて何をやっているのか分からないです。

ですので、具体的に何をしているのかを明確な名前を使うべきです。

『Check』という単語の代替案は下記の通りです。
isNull, isEmpty, isNullOrEmpty, isValid, canSave, canClose,
hasSaved, hasChanged, exists, contains, etc...

 

要点4: 理由なしに汎用的な名前は使わない

『retval』『temp』『foo』などの名前はよく汎用的な名前といわれますがこれらの名前を使うのは推奨されていません。

例えば『retval』を使っている関数があったとします。

例:

int calc_square(int l){

    int ret_val = l * l;

   return ret_val;

}

良い名前が思いつかなければ、例のように戻り値に『retval』のような汎用的な名前を使いたくなるものです。

ですが、『retval』には「自身が戻り値である」以外の情報を持っていません。

良い名前は変数の目的や意味を表すものです。ここではlの2乗を表してるので、『sum_square』という名前が良い名前として挙げられます。

これによりもじ処理が

int sum_squares += l + l;

という風に書き間違っていた場合、変数名の表す意味と代入する内容が異なっているのでこの間違いに気づきやすくなります。

 

一方で汎用的な名前を使うことが推奨される場面も存在しています。

例:

if(right > left){

    temp = right;

    right = left;

    left = temp:

}

このような場合は、tempという名前で問題ないです。

なぜなら、この場面のtempは「情報の一時的な保管」であり、それ以上の意味を持たないからです。

しかも、このtempという変数のスコープはわずか数行であり、複数のtempが干渉しあうということもあり得ません。

故に、このような場合はtempという名前を使うことが推奨されます。

当然、このtempに「情報の一時的な保管」以外の処理を加えるのであれば、名前を考え直す必要があります。

 

 

ということで『命名』の話は以上です。

元々の本の内容はだいぶ省略しているので 、詳しく勉強したい人は自分で読んでみて下さい。


参考文献:

 

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

www.hassy-blog.com

algorithm.joho.info

プログラミングでよく使う英単語のまとめ【随時更新】 - Qiitaqiita.com

qiita.com

 

www.weblio.jp

 

はじめに — pep8-ja 1.0 ドキュメント