CODE COMPLETE 第11章 変数名の力
ゆるWeb勉強会@札幌 Advent Calendar 2019 21日目の記事です。
命名とは、最小単位の設計行為である
というのはかの有名な誰それの言葉、でもなんでもなく自分が勝手に思っていることなのですが、プログラミングを初めてから2年弱経ち、その中で命名について思うことが度々あったので、
今回は「コーディングにおける名付け」について書いてみたいと思います。
設計はなんだか難しい・・・でも出来ることからちょっとずつやってみたい、
そんな時は命名についてちょっとしたこだわりを持ってみると手軽にコードを綺麗に出来るかもしれません。
課題図書について
何か道しるべ的なものが欲しいなと思い、適当に参考文献をいくつか漁っていたのですが、だいたいどの資料でも参照・言及されていたのが表題の『CODE COMPLETE』です。
今回はこちらの上巻第3部第11章変数名の力を読んでみてのまとめと感想的な内容になります。
ご存知の方・お持ちの方もいらっしゃるかもしれませんが、CODE COMPLETEはプログラミングにおける設計やコーディングについて体系的にまとめられた内容になっており、結構なボリュームになっています(お値段もボリューミーでした・・)
上巻だけでも全628ページあり下巻と束ねれば完全に鈍器といって差し支えない分量なので、一家に一組あれば結構な暇つぶし、もとい勉強になりそうです(いざという時は鈍器になるので防犯的にもよさそう)
個人的にはLTやブログのネタに困った時に1章分読んでそこからテキストやスライド資料に落とし込むこともできそうだなあと思ったりもしたので、また機会を作って別なテーマでアウトプットしてみるのもいいかなと思いました。
また今回は課題図書の都合上、BEMによるcss命名規則やVue.jsのコンポーネント名のルールなど、言語仕様に関わる命名の話題はなしで行きたいと思います。
前置きおしまい。
本題
良い命名について考えてみる
コーディングをしていて、変数やクラス・メソッドに名前を付けたことが全くない、という人は多分いないんじゃないかと思います。
さてコードを書くぞとなったとき、プログラマはどのような考えで変数に名前をつけるでしょうか。
- 変数に入れるデータがなんなのかがわかるように名付ける
- 名前がかぶったりせずプログラムが正常に動作するように名付ける
- 後で見返したりレビュアーがわかりやすい単語で名付ける
- プロジェクトのコーディング規約があればそれにしたがって名付ける
他にも命名の基準はありそうですが、だいたい上記のような考えに基づいて名付けが行われることが多そうです(主観)
では良い命名とはなんでしょうか?
また、良い命名をすることの意味とはなんでしょうか?
自分はこの問いに対する明確な答えがわかりませんでした。もし良い命名を積極的に意識して行うことによるメリットがあるのならば、実践してみる価値はありそうです。
第11章の冒頭で具体例を交えてこんな一文がありました。
良い変数名は、読みやすく、覚えやすく、適切である
なるほど、確かに。なんとなくわかる気がします。
最近は仕事でも不具合報告からの調査作業からの既存ソース確認、みたいなことが度々あるのですがソースを追いかけていて楽に感じることと辛く感じることがあります。大抵辛い時は↑の3つに乗っ取った書き方になっていなかったりしていた気がします(つらい要因は他にもありそうですがそれはまた別の話で)
良さの基準の話
- 読みやすく
- 覚えやすく
- 適切
とはいえこの3つは言ってしまえばそりゃそうだ、という話です。自分が知りたいのはもっと具体的で、簡単な良い命名の基準なのです。どうすればばっちり迷いなく名付けができるのか?
もう少し読み進めるとこんな記述があります。
変数に名前を付けるときに最も重要なことは、変数が表すものを完全かつ正確に説明するような名前を付けることである。
おお、とても具体的です。試しにこの基準に則って命名してみましょう(本文からの抜粋)
// ①アメリカのオリンピックチームに所属する選手の数
let numberOfPeopleOnTheUsOlympicTeam = 10;
// ②現行の利率
let interestRate = 1.1;
// ③現行の利率(よくない例)
let r = 1.1;
// ④現行の利率(おしいけどよくない例)
let rate = 1.1;
①や②は解読しやすく自明な単語が使われています。誰が読んでも同じように何を示しているかわかるでしょう。
とはいえ、①は実用的とはいえないほど長いです。こんな長さの変数がぽんぽんコード上に出てきてしまったら正直うんざりします。
③は短すぎて何を示しているかの情報が全くありません。変数rの正体を掴むには前後関係を追うか、運良くコメントがついていればそれを参照するしかなさそうです。
④は何かの割合・利率であることはわかりますが、もしソースの前後に現行の利率の他に過去の利率や登録人数の割合があったとしたらおしまいです。
一つの基準として、本文では変数名の長さが平均して10〜16文字程度だとデバッグが最も手間がかからないとの記述がありました(必ず↑の長さでなければいけないわけではなく、これより短い変数名が目につく時は変数名の変更を検討すべき、くらいの意味とのこと)
また一覧表の中に丁度良い長さの変数名の具体例が記述されていたのですが、だいたいどれも2・3単語で表現できているという共通点がありました。確かにこれくらいなら長すぎず短すぎず丁度良さそうです。
(逆に2・3単語で表現できないものを変数として定義すること自体避けるべきなのかも?)
短い変数名は有無を言わさず滅ぶべきなのか?
ここまでの基準で言えば、"i"とか"size"とかそういう変数名はよろしくないということになります。ではこのような自明でない変数名は抹殺するべきでしょうか?
実際のところどうなのでしょう。
自分は、for文などで局所的な用途であれば別にいいんじゃないかなとなんとなく考えていたのですが、この辺りについては一つの答えが書かれていました。
変数にiといった短い名前を付けると、長さそのものが変数について何かを伝えるーーつまり、その変数が限られた処理スコープを持つ一時的な変数であることを示す。
これはちょっとした目から鱗情報でした。普段は、自明な単語を用いて正確な変数名を使っておいて、短い変数名はここでしか使いませんよ、というルールに基づいて運用すれば短さ自体に意味を持たせることができるというわけです。かしこい。
ループ変数の命名
ループの話が出てきたので、forやwhileでよく使うカウント目的の変数について触れてみます。
大抵のプログラミング言語ではi, j, kがよく使われます。基本的にこれらはお決まりの名前として周知されているということもあり、ループ内だけに限って言えば短さが逆に生きてきそうです。
もしiやjがループの外側でもなんらかの役割を持っているならば、ひと工夫あると良いようです。
recordCount = 0;
while ( moreScores() ) {
score[ recordCount ] = GetNextScore();
recordCount++;
}
if ( recordCount < 100 ) { // なにか処理する }
または、ループが結構な長さになってくる場合も同様に良き名前をつけてやると可読性が上がりそうです。
あるいはループが入れ子になっている場合もi, j, kで済ませたりすると辛そうです。
外側のループ・内側のループで明確に区別できる変数名を用意すると良さそうです。
↓個人的にこういうのは結構嫌いです(たまにみかける)
foreach ( $userList as $index => $value ) {
foreach ( $codeList as $index2 => $value2 ) {
// なんかやる
}
}
(余談ですが$userListの1件目を$valueで表現しているのもつらいポイント結構高めです。$valueってなんだよ、ってなってしまう)
計算値による変数名の修飾
プログラムの処理上、足したり・掛けたり・集計したりとなんらかの計算をしてその結果を変数に入れておくような場面も多いと思いますが、 そのような値を入れておく変数名にはお決まりの修飾語を付けるようにすると良いようです。
たとえば、
- totalSum
- pointAverage
- expenceRecord
のように「[ 何の ] + [ 計算 ] した値」と表現する感じでしょうか。このルールで統一していけばかなりコードが読みやすくなりそうです。
本文では付け加えるように
名前に一貫性があるとコードが読みやすくなり、保守作業が容易になる。
と記載されていました。プレフィックスなのかサフィックスなのかは、最低限コーディングルールとして定めておくのが良さそうです。
ちょっとだけ話は変わりますが例えばキャメルケースとスネークケースが無秩序に混在していると確かにそれだけでテンションが下がってしまいます。
あとで読み直した時にテンションの上がるソースであってほしいものですね。
また、計算値の修飾についての例外について一つ記載がありました。
Num修飾子は位置が慣習的に決まっているため、変数名の先頭に付けると合計を意味するのに対し、末尾につけるとインデックスを意味する修飾になるそうです(ぜんぜん知らなかった・出来れば上記の根拠やルールのソースが読みたかったのですが本文でも言及されておらず、ググってもよくわからず)
以上のような背景もあるのでそもそもNumは多用しないのが無難、おとなしくtotalやindexを使えばええやん、的に締め括られていました。確かに。
おわりに
本書では他にも色々と変数名について有益な情報が載っていましたが、それはまた別の機会に記事に(または本記事の更新を)してきたいと思います。
特に命名規則に関する説明が結構ページ数多めに書かれていたのですが、これはこれで別な形でまとめてみたいです。(いつか自分がプロジェクトの命名規則を作ることがあるかもしれない)
本書が気になった方は、ぜひ書店等でお買い求めいただければと思います。
鈍器版(紙版)はちょっと・・という方はamazonで上下巻合本の電子書籍版も出ているようなので、持ち運びの利便性重視の方や人の頭をかち割る予定のない方はこちらが良いかもしれません。
【電子合本版】Code Complete 第2版 完全なプログラミングを目指して
- 作者:Steve McConnell
- 出版社/メーカー: 日経BP
- 発売日: 2016/04/14
- メディア: Kindle版
お値段もほんのわずかですが安いです。
最後になりますが、冒頭でも書いたように本記事はtacckさん主催の勉強会「ゆるweb勉強会」のアドベントカレンダー企画に参加させていただいたものになります。
個人的に、今年は仕事外でも自主的に勉強をしてみようという余力がほんの少しでも出来たこともあり、札幌市内の勉強会や道外のカンファレンスにもいくつか参加することができました。
その中でもゆるweb勉強会では何かと勉強の機会をいただいて大変お世話になりました。
tacckさん、いつもありがとうございます。来年もどうぞよろしくお願いいたします。