tag:crieit.net,2005:https://crieit.net/tags/%E5%91%BD%E5%90%8D/feed 「命名」の記事 - Crieit Crieitでタグ「命名」に投稿された最近の記事 2021-05-12T21:20:27+09:00 https://crieit.net/tags/%E5%91%BD%E5%90%8D/feed tag:crieit.net,2005:PublicArticle/17099 2021-05-12T21:20:27+09:00 2021-05-12T21:20:27+09:00 https://crieit.net/posts/regist-or-register 【プログラミング全般】「登録する」の意でregistと書くことの是非について <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>「登録する」という意味でregistと書くのがあるあるなのかは分かりませんが、色んなプロジェクトで色んな人が書いたコードを見ても、結構registが使われていました。</p> <p>英語的には誤りであり、registという単語は存在しません。正しくはregisterです。ではなぜregisterではなくregistが使われているのか、そう書いた人ひとりひとりを捕まえて「あなたはなぜregiterではなくregistと書いたのですか?」とインタビューすることはできないので、勝手に推測しています。</p> <h1 id="registerではなくregistを使う理由を推測"><a href="#register%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Fregist%E3%82%92%E4%BD%BF%E3%81%86%E7%90%86%E7%94%B1%E3%82%92%E6%8E%A8%E6%B8%AC">registerではなくregistを使う理由を推測</a></h1> <h2 id="-erが動詞っぽくないから"><a href="#-er%E3%81%8C%E5%8B%95%E8%A9%9E%E3%81%A3%E3%81%BD%E3%81%8F%E3%81%AA%E3%81%84%E3%81%8B%E3%82%89">-erが動詞っぽくないから</a></h2> <p>個人的には一番それっぽい理由だと思います。</p> <p>registerはまぎれもなく動詞なのですが、-erという接尾辞が「~する人」ということを表すので、-erを抜いたregistが「登録する」ということなのだろう、と思ったのではないかということですね。まぁ分からなくはないですが、辞書引こうよ…とは思いますね。</p> <h2 id="慣習になっているから"><a href="#%E6%85%A3%E7%BF%92%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E3%82%89">慣習になっているから</a></h2> <p>自分たちが手をつける以前のソースコードでびっしりとregistが使われており、registerを使いたいけど統一感なくなるのも気持ち悪いので、いやいやregistを使っているパターンですね。</p> <h2 id="短い方がいいから"><a href="#%E7%9F%AD%E3%81%84%E6%96%B9%E3%81%8C%E3%81%84%E3%81%84%E3%81%8B%E3%82%89">短い方がいいから</a></h2> <p>registerという語であることは知っているけど、registの方が短いしチーム内で意味も伝わるからregistにしているパターン。これもなくはないでしょうし、ベテランエンジニアがこんな感じで書いてたら他のメンバーも合わせざるを得ないみたいな感じになりそうです。</p> <p>insert→ins、update→updみたいに省略してもある程度意味が伝わるので、わざわざregisterと書く必要はないじゃんという発想かもしれません。</p> <p>おそらく上記のような理由があるのではないかと思います。</p> <h1 id="ググってみる"><a href="#%E3%82%B0%E3%82%B0%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">ググってみる</a></h1> <p>「登録する regist プログラマ」みたいなキーワードでググってみたところ、以下の記事がヒットしました。</p> <p><a target="_blank" rel="nofollow noopener" href="http://yanok.net/2010/08/-regist.html">「登録する」の罠: registは間違い、アクセントにも注意</a></p> <blockquote> <p>registerではなんとなく動詞らしく見えないので、こういう勘違いが発生してしまうのでしょう。</p> </blockquote> <p>「動詞っぽくないから説」を提唱されています。私もそう思います。ちょっとややこしい単語ではありますよね。</p> <p>この記事へ反応する形で、次のような記事もありました。</p> <p><a target="_blank" rel="nofollow noopener" href="http://talkingnonsense.coolk2.com/?p=303">正確さよりも意図が“素早く正確に伝わる”ことが重要 - 2011年09月05日</a></p> <blockquote> <p>プログラマやSEにとって、この単語が正しい英語かなんてどうでもいいことだ。さらに発音なんてさらにどうでもいいことだ。重要なことは、この単語を見た人間(おそらく同じプログラマかSEか)が、この単語が付いた機能なりファイルなりの概要を名前から安易にかつ正確に想像できるか?という点にある。</p> </blockquote> <p>これに関しては半分同意といいう感じです。発音に関しては個人的にはどうでもいいと思います。それは私の周りにもネイティブの英語話者がいないからかもしれないですが、コードレビューしていて「このトライアップロードメソッドは何をしているの?」みたいにカタカナ英語で言いますし双方通じています。</p> <p>ネーミングから容易に処理が分かるかというのも大事な視点です。</p> <blockquote> <p>たとえば、認証という単語はrecognitionやcertificationを使うのが妥当だと思われる。しかしrecognitionやcertificationという単語はあまり馴染みが無い。意味を調べるのに辞書を要する人間も多いだろう。さらに文字数も多すぎる。それを考慮して、俺は認証をする機能にはauthという略語(造語?)を良く使う。</p> </blockquote> <p>これに関しても同意できます。一方、英語の細かいニュアンスの違いを命名に落とし込んであると、より良いコードだなと思うこともあります。たとえば</p> <ul> <li>beginとstartの違い</li> <li>deleteとremoveの違い</li> <li>sinceとfromの違い</li> </ul> <p>などがコードリーディングを助けることもあるでしょう。</p> <p>例として挙げられているものでも、たとえばrecognitionだと「一度認識しているものを改めて認識する」ようなニュアンスの認証ですし(接頭辞re-が付いていますね)、certificationだと「何かを申請して、それが他の誰かに承認される」ようなニュアンスの認証、auth(authentication)だとIDとパスワードを使って認証(本人確認)するようなニュアンスの認証です<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。これらのニュアンスの違いがあるのに、認証は全部authでいいや!というのはちょっとどうかと個人的には思います。</p> <h1 id="英語はやっぱり大事"><a href="#%E8%8B%B1%E8%AA%9E%E3%81%AF%E3%82%84%E3%81%A3%E3%81%B1%E3%82%8A%E5%A4%A7%E4%BA%8B">英語はやっぱり大事</a></h1> <p>そういう意味では、「正しい英語」というのはニュアンスの違いなどの理解が及ぶ範囲であれば、それは重要だと個人的には思います。ただ、registとregisterに関してはニュアンスの違いとかではなくそもそも存在しない語と存在する語の違いなので、ここでは若干違う話題ではありますが。</p> <p>また、プログラミングはだいたい英語を使うため、正しい英語の重要性みたいなのを理解していないとトンチンカンなコードを書いたりします。一度directoryPassみたいな変数を見たことがあります(おそらく書きたかったのはdirectoryPath)。pathは結構頻出基礎的な単語だと思うのですが、自分より何年も長くコードを書いているような人が間違えていると、ある程度正しい英語を使うクセ付けというか、そういうのは大事だよなぁとも思います。少なくとも分からなかったらググる、あまりにも長くなりそうだったらローマ字で書くとかが「正確に伝わる」という意味ではアリだと思います。ローマ字の是非はまた議論が別れそうですが、個人的にはpathをpassと書かれるくらいならpasuと書いてもらった方が…いやpathくらい覚えてほしいな、やっぱ。</p> <p>個人的にはregistだろうがregisterだろうが意味は伝わるので、既にregistが使われているプロジェクトではregistを使います。でも自分が0から作るならregisterを使います。IDEの補完機能などを使えば2文字増えようが関係ないですし、逆に2文字をケチって「あれwこの人registっていう英単語はないって知らないのかな?ぷっぷくぷーw」と思われるくらいならしっかり書きます<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>。まぁ思われても別にいいですけど。</p> <p>結局は環境次第ということだと思います。メリットデメリットあるので、ある程度クローズドな環境であればregistでもいいんじゃない?とは思いますね。ただ、世界中に公開するようなコードを書くのであればregisterを使っていた方が無難だとは思います。少し紹介しましたが、insert→ins、update→updで伝わるのになんでregistはダメなんだ!と思われたら、中途半端に略してて気持ち悪いからだと思います。中途半端にerだけ省略しても誰も幸せにならないのでregくらいまで省略すれないいんじゃないですかね?regだったら省略しているということが明かなので。registだと若干ひっかかるというか、気持ち悪い感は否めないです。個人的に。</p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1" role="doc-endnote"> <p>私の理解が正しいかはわからないので鵜呑みにしないでくださいね。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:2" role="doc-endnote"> <p>私がregist派のみなさんをそのように思っているという訳ではないですよ。 <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div> あぱしょに tag:crieit.net,2005:PublicArticle/16572 2021-01-09T22:31:27+09:00 2021-06-03T20:45:52+09:00 https://crieit.net/posts/csharp-naming 【C#】命名って大事だね <p>命名って大事だよね、ということはコードを書く人であればだいたい同意していただけると思う。</p> <p>というかコードを書かない人も「memo.txt」と「〇月〇日までに買う予定リスト.txt」だったら、ファイルの内容が同じでも後者の方が圧倒的にわかりやすいとは思っていただけると思う。</p> <p>毎度毎度弊社の困ったちゃんのことを書くのは忍びないが、だけど書くが、困ったちゃんははっきり言って命名がヘタクソである。私も別に命名に自信ニキという訳ではないが、まぁ困ったちゃんよりは上手く命名していると思うし、自分の命名で困ったこともあまりないので書いてみる。</p> <p>以降、サンプルコードにC#を用いるが別にどの言語でも共通する話だと思う。難しいことは書かないのでC#がわからなくてもだいたい読めると思う。</p> <h1 id="なぜ命名が大事か"><a href="#%E3%81%AA%E3%81%9C%E5%91%BD%E5%90%8D%E3%81%8C%E5%A4%A7%E4%BA%8B%E3%81%8B">なぜ命名が大事か</a></h1> <p>簡潔に言うと情報量の違いだと思う。</p> <p>極端な例だが、次のような変数宣言があるとする。</p> <pre><code class="csharp">decimal price = 100; </code></pre> <p><code>price</code>は価格・値段といった意味だが、はっきり言って<code>price</code>という文字だけでこれが何に使われるのか正確にはわからない。</p> <p>具体的には以下のような情報が欠けている。</p> <ul> <li>単価?小計?合計?</li> <li>税込み?税抜き?</li> <li>(キャンペーンなどがある場合)割引適用前?適用後?</li> <li>単位は日本円?ドル?</li> </ul> <p>こういった情報はできるだけ変数名に明示的に盛り込むべきだと考える。</p> <pre><code class="csharp">// 単価なら decimal unitPrice = 100; // 小計なら decimal subTotal = 100; // 合計なら decimal total = 100; // 税込みなら decimal taxIncludedPrice = 100; // 税抜きなら decimal taxExcludedPrice = 100; // 割引適用前なら decimal undiscountedPrice = 100; // または originalPrice // 割引適用後なら decimal discountedPrice = 100; // 単位が縁 decimal price_yen = 100; // 単位がドル decimal price_dol = 100; </code></pre> <p>といった具合に変数名に情報量を持たせることで可読性を上げることができる。</p> <p>この考え方は一部、アプリケーションハンガリアンといわれる考え方と一致する。</p> <p>たとえば、</p> <pre><code class="csharp">decimal total = price_yen + price_dol; </code></pre> <p>のようなコードはドルと日本円を加算しており、明らかに間違いだということが<strong>見ただけで</strong>分る。正しくは</p> <pre><code class="csharp">// ドルは円に換算して可算する decimal total = price_yen + ConvertToYen(price_dol); </code></pre> <p>としなければならないと判断できる。これが命名が持つ強力なメリットであり、命名にこだわる理由である。</p> <p>こういった考え方が活きる場面はたくさんある。</p> <pre><code class="csharp">// パスワード string password = "XXXXX"; // パスワードを更新 user.updatePassword(password); </code></pre> <p>これだと、<code>password</code>で更新しているが、うっかり<code>password</code>が平文のままだったら平文がそのまま登録されているかもしれない。</p> <p>もし変数名を<code>plainPassword</code>などとしていれば平文のパスワードということが見ただけで分かるので、登録前にハッシュ化させる必要があると気づけるだろう。</p> <pre><code class="csharp">// 平文のパスワード string plainPassword = "XXXXX"; // ハッシュ string hashedPassword = plainPassword.Hash(); // ハッシュ化されたパスワードで更新 user.updatePassword(hashedPassword); </code></pre> <p>また、コーディングミスにより</p> <pre><code class="csharp">// 誤って平文で更新するコードになっている user.updatePassword(plainPassword); </code></pre> <p>と書いてしまっていたとしても、「平文で更新するっておかしいよね?」と気づくきっかけになるハズだ。</p> <p>このような「これは税計算必要なの?」「これは平文?」などの情報はよくコードを読めば分かることではある。だがその「よくコードを読む」作業を意識から切り離して、本来考えたいアルゴリズムや可読性などに集中できるのが大事だ。そしてそれは命名の工夫をするだけで改善できることでもある。</p> <p>汎用性の高い接頭辞や接尾辞もあるので、それらはいつでも使えるようになっておくとベストだ。</p> <h1 id="xxxFlgという変数名"><a href="#xxxFlg%E3%81%A8%E3%81%84%E3%81%86%E5%A4%89%E6%95%B0%E5%90%8D">xxxFlgという変数名</a></h1> <p>真偽値などで<code>xxxFlg</code>などという命名をしているのをたまに見かけるが、これもあまり優しくないと思う。</p> <p>例えば<code>deleteFlg</code>という変数名があるとする。これは以下のように様々な解釈が可能である。</p> <ul> <li>削除済みのデータであることを示すフラグ</li> <li>削除できる状態のデータであることを示すフラグ</li> <li>削除しなければならないデータを示すフラグ</li> <li>削除される予定のデータであることを示すフラグ</li> </ul> <p>などだ。<code>delete</code>としか書かれていないのだから如何様にも解釈できる。<code>true</code>で削除済みなのか<code>false</code>で削除済みなのかも、変数名からは分からない。個人開発ならともかく、チームで開発するプロジェクトにおいて「そんなつもりで命名した訳じゃない」「普通に考えたらこう」なんていうのは通用しない。何故ならそのコードは自分だけではなく、他の誰かが読んだり修正したりするかもしれないからだ。個人開発だとしても、何日も経って忘れたころに見直すこともあるだろう。だからこそ、直感的に分かりやすい命名をする必要がある。</p> <p>真偽値の命名には<code>is</code>, <code>has</code>, <code>can</code>(もしくは<code>is~able</code>), <code>should</code>などを使うと可読性が上がると言われている。それらはY/N質問として読めるし、意味のはき違えようがないからだ。</p> <pre><code class="csharp">// 削除済み bool isDeleted = true; // 削除できる bool canDelete = true; bool isDeletable = true; // 削除しなければならない bool shouldDelete = true; </code></pre> <p>これだと、<code>isDeleted</code>は「削除済みか?」に対して<code>true</code>(削除済み)か<code>false</code>(削除済みではない)とハッキリするのである。<code>isDeleted</code>という変数名で「<code>true</code>だから『削除しなければならない』ってことだな!」「<code>true</code>だから未削除なんだな!」と解釈する人はまずいないだろう。それは考え方とかじゃなくて英語力の問題だから…。</p> <h1 id="コメントで補えるのでは"><a href="#%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A7%E8%A3%9C%E3%81%88%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%AF">コメントで補えるのでは</a></h1> <p>命名をシンプルにしてコメントで補えるのでは、と思うかもしれない。確かにそういう手もあるが、個人的には望ましくないと考える。なぜか。</p> <p>それはコメントはメンテしないといけないからだ。</p> <pre><code class="csharp">// 税抜き価格 decimal price = 100; </code></pre> <p>というコメントをつけたコードがあったとする。これが税込み価格を反映するという修正が必要になった場合、</p> <pre><code class="csharp">// 税抜き価格 decimal price = 110; </code></pre> <p>と修正するだけでなく、コメントも</p> <pre><code class="csharp">// 税込み価格 decimal price = 110; </code></pre> <p>と直さなければならなくなる。修正の工数がしっかり確保されており、コメントも含めてレビューされるような環境であればまだいいかもしれないが、多くの場合修正レビューはテストが通るかどうかと差分の比較であり、コメントは忘れ去られる。動作は自動テストが保障してくれるかもしれないが、コメントが合っているかどうかは人の目でみないと分からない。</p> <p>もしコメントのメンテを怠ると、そのコメントは嘘になる。コメントに嘘が書いてあるくらいなら、コメントがない方が100倍ましだ。そうやって嘘のコメントが積み重なって保守不可能な過去の遺産になっていく。コメントで意味を補足するくらいなら、<code>taxExcludedPrice</code>や<code>taxIncludedPrice</code>などの具体的な意味を持った命名をした方が良い。</p> <h1 id="システムハンガリアンは…"><a href="#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E3%81%AF%E2%80%A6">システムハンガリアンは…</a></h1> <p>前述した「アプリケーションハンガリアン」とは別に「システムハンガリアン」という考え方もあるが、これは現代ではもはや推奨されていないシーンの方が多い。以前は私も使っていたが、最近はまず使わないようになった。</p> <pre><code class="csharp">string sName = "あぱしょに"; int nAge = 27; </code></pre> <p>システムハンガリアンは、<code>string</code>型なら<strong>s</strong>や<strong>str</strong>、int型なら<strong>n</strong>や<strong>int</strong>のように、各変数の型を識別できる接頭辞を入れるというものだ。</p> <p>これも同様にコードを見ただけでエラーが分かるようになるというハックの一つだが、静的型付け言語ではたとえば</p> <pre><code class="csharp">string sName = "あぱしょに"; int nAge = 27; int hoge = nAge * sName; // エラー </code></pre> <p>などと間違えて書いても<br /> <a href="https://crieit.now.sh/upload_images/9efd38256758a1d84d90e3d5578cfd715ff9b00d04cd3.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9efd38256758a1d84d90e3d5578cfd715ff9b00d04cd3.jpg?mw=700" alt="image" /></a><br /> のように教えてくれるので、変数を見ただけで型の不一致がわかるというメリットは少ない。動的型付け言語であれば違うと思うが…。</p> <p>また、システムハンガリアンは型を変更した際に変数名も修正しなければならない(そうでないとシステムハンガリアンのメリットが正しく発揮されない)。たとえば<code>nUserId</code>を<code>int</code>型から<code>string</code>型に変更した場合は、型だけでなく変数名も<code>sUserId</code>と変更しなければならず、これは大変な手間である。</p> <p>そういった理由で、システムハンガリアンは現代ではほとんど見られなくなった(少なくとも私の観測範囲では)。これからも私が積極的に使うことはないだろう。昔の案件の修正などで既にコーディングスタイルが指定されていれば従うが。</p> <h1 id="英語にこだわらなくていい"><a href="#%E8%8B%B1%E8%AA%9E%E3%81%AB%E3%81%93%E3%81%A0%E3%82%8F%E3%82%89%E3%81%AA%E3%81%8F%E3%81%A6%E3%81%84%E3%81%84">英語にこだわらなくていい</a></h1> <p>個人的には無理して英語にこだわって意味不明な変数名になるよりは、別にローマ字でもいいから意味が分かるよう正確に命名してほしいと思っている。</p> <p>また、英語に自信がなければ<a target="_blank" rel="nofollow noopener" href="https://codic.jp/">codic</a>や<a target="_blank" rel="nofollow noopener" href="https://www.deepl.com/translator">DeepL</a>など便利なサービスもあるので、それらも活用したい。特に前者はネーミングに特化しているだけでなく、<code>camelCase</code>や<code>snake_case</code>、<code>PascalCase</code>など自由にスタイルをカスタマイズできる。私はこれらのサービスで色んな語を知った。</p> あぱしょに