こんにちは、サーバーサイドエンジニアの横山です。
皆さんは、変数名やメソッド名(関数名)をどのように決めていますか?
私はよく変数やメソッドの命名に苦労しています。 ChatGPTに質問してみたり、翻訳してみたりしますが、しっくりくる名前に中々辿り着けず。 処理よりも命名に時間を費やしてしまうこともあります...。
最近、変数やメソッドを命名する機会が多くなっていたので、配慮すべきポイントを整理してみました。
命名が適切でない場合のデメリット
- コードが読みづらい
- 処理内容を理解するのに時間がかかる
- 誤った認識がされてしまうとバグの要因になる
理想的な命名
- 変数名やメソッド名を見るだけで、どんな処理をしているか分かる
- 適切な長さと抽象度
- 同じ種類の処理やデータに対して一貫性がある
配慮すべきポイント
単語選び
処理内容を名前で表すためには適切な単語選びが必要ですが、選択肢が多すぎるとどれを選べばいいか迷ってしまうことがありませんか?
例えば、何かを終わらせる処理を作成するため、メソッド名に「終わり」を意味する単語を使いたいとします。ですが「終わり」という単語は、パッと検索しただけでも選択肢が複数出てきます。
finish, done, end, close, last, final, ....
ここで以下4つのの意味を ChatGPT に質問してみました。
finish
:プロセスやタスクを終わらせることdone
:何かがすでに完了した状態や結果end
:時間や範囲の終了close
:接続やセッション、アプリケーションなどの終了
つまり、セッションを終わらせる処理は、close_session
、プロセスを終わらせる処理は finish_xxx(タスク名)
のように命名できます。
「停止」という単語の場合はどうでしょうか?
stop
:完全に何かを停止することpause
:一時的な停止。通常は同じ状態やポイントから再開する可能性がある。suspend
:一時的な中断。必ずしも再開する保証はなく、特に重要な活動やプロセスの一時停止させる。
「停止」でも、完全に停止させるのか、一時停止なのか、そして再開する可能性があるのか..処理内容によって選ぶべき単語が明確になりました。
このように、単語の意味を詳しく調べることで、文脈や処理内容に応じて適切な単語を選ぶヒントが得られます。
抽象度
私はよくメソッド名を具体的にしすぎてしまうことがあります。
ある日付から1ヶ月後に有効期限が切れる場合、その有効期限が切れているかを調べるメソッドを作ったとします。
私が最初に考えついたメソッド名は以下の通りです。
def expired_after_one_month? Date.today > date + 1.month end
このメソッド名は処理の内容をそのものを示しており、具体的すぎるメソッド名となりました。
そのため特定の状況に限定されてしまい、将来的な変更に対応しづらくなります。
もし有効期限が2ヶ月後に変更された場合、メソッド名も変更しなければなりません。
そこで以下のように1段階抽象化すると、メソッドの用途がより一般化されます。
def past_expiration_date? Date.today > date + 1.month end
さらに簡潔にすると、以下のようになります。
def expired? Date.today > date + 1.month end
end?
だと抽象的すぎて分かりづらいですが expired?
という単語だけでも「日付の期限切れ」を意味するため、(コンテクストにもよりますが、)簡潔に記載しても良い場面もあると思います。
メソッド名は具体的すぎず、抽象的すぎないバランスを意識することが重要です。こうすることで、コードの柔軟性が保たれ、将来的な変更にも対応しやすくなります。
参考記事: 名前重要!具体的過ぎるメソッド名や変数名の弊害と適切な抽象度 | FJORD BOOT CAMP(フィヨルドブートキャンプ)
長さ
名前の長さも重要な要素となります。 長すぎる名前は読みづらくなったり、コードの行数を増やしてしまったりする可能性があります。逆に短すぎる名前では意味が伝わりにくく、他の変数やメソッドとの重複も起こる可能性があります。
O'Reilly Japan - リーダブルコードによると、名前の長さは以下のように設定すべきだとされています。
- スコープの大きな変数には、長い名前をつける
- スコープが小さい変数には、短い名前でも問題ない
- 名前が長すぎる場合でも、プロジェクト固有の省略形は避けるべき
例えば、メソッド内でのみ使用されるローカル変数等はスコープが狭いため、短い名前でも問題ありませんが、 インスタンス変数等が広く使用される場合は、意味が明確で他と区別しやすい名前を選ぶことが必要となります。
述語メソッド(boolean)
通常、述語メソッドの末尾に?
を付けることが一般的ですが、その他にも is
やcan
といった接頭辞を付けることで、メソッドが真偽値を返すことが明確になり、読みやすさが向上すると考えられています。
しかし、Ruby Style Guide によると、特定の接頭辞を述語メソッドに使用することは避けることが推奨されています。
Avoid prefixing predicate methods with the auxiliary verbs such as is, does, or can. These words are redundant and inconsistent with the style of boolean methods in the Ruby core library, such as empty? and include?.
例えば、is_paid?
というメソッド名は paid?
と is
を省略しても同じ意味が通じますし、むしろより簡潔ですね。
接頭辞を使用した方が分かりやすい場合もあると思いますので、全体的なコード内で統一できると良いと思います。
おわりに
命名は、処理内容やコンテクスト、プロジェクト・チームの規則や個人の好みによって異なることがありますので、これが正解...というものはないと思います。 ただ、適切な命名は可読性や保守性を向上させる重要な要素であるため、自分自身も良い命名ができるよう引き続き模索していきたいです。
ユニファでは、一緒に働く仲間を募集しています! unifa-e.com