命名する際、どういう名前にするべきかについて指針がなくて困っていたので、リーダブルコードを読み始めたので、それについてまとめていきたいと思います。
鍵となる考え
名前が他の意味と間違えられることはないだろうか?と何度も自問自答する。
filter()
データベースへの問い合わせで以下のようなコードがあるとする。
results = Database.all_objects.filter("year <= 2011")
これではresultsに何が含まれているかわからない。
- 「year <= 2011」のオブジェクト
- 「year <= 2011」でないオブジェクト
なぜわからないかというと、filterがあいまいな言葉だからだ。以下のように、selectやexcludeを使うとわかりやすい。
# 「year <= 2011」のオブジェクト
results = Database.all_objects.select("year <= 2011")
# 「year <= 2011」でないオブジェクト
results = Database.all_objects.exclude("year <= 2011")
Clip(text, length)
段落の内容を切り抜く以下の関数があるとする。
def clip(text, length)
このメソッド名から2つの動作が考えられる。
- 最後からlength文字を削除する (remove)
- 最大length文字まで切り詰める (truncate)
clipでは複数の動作が考えられてしまうため、ここはより具体的なtruncateを関数名に使うのがいい。また、lengthも以下のように複数考えられるため、名前に単位を使ったほうがいい。
- バイト数
- 文字数
- 単語数
def trancate(text, max_char)
限界値を含めるときはminとmaxを使う
if shopping_cart.number_of_items > MAX_ITEMS_IN_CART
# 処理
範囲を指定するときはfirstとlastを使う
以下では、最後を含めるのか含めないのかあいまいである。
puts integer_range(start=2, stop=4)
[2, 3]か[2, 3, 4]なのかがあいまい
包含的な範囲を示すならlastを使ったほうがより明確になる。
包含 / 排他的範囲にはbeginとendを使う
例えば10月16日に開催されたイベントをすべて印字したいとする。
print_event_in_range("OCT 16 12:00am", "OCT 17 12:00am")
ここに使う仮引数の名前だが、プログラミングの命名規則では包含 / 排他的範囲にbeginとendを使うことが多い。endは少しあいまいだが、これが最善の選択である。
print_event_in_range(begin="OCT 16 12:00am", end="OCT 17 12:00am")
ブール値の名前
ブール値の変数やブール値を返す関数の名前を選ぶときには、trueやfalseの意味を明確にしなければいけない。
read_password = true
上のような例だとパスワードをこれから読み取る必要があることを意味しているのか、パスワード読み込み後なのかがわからない。need_passwordやuser_is_authenticatedを使ったほうが分かりやすい。Railsではbooleanを返すメソッドは語尾に?をつける慣習があるため、Userのインスタンスメソッドとして定義する場合は、need_password?やauthenticated?とする。
また、disable_sslのような否定形での定義も避けたほうが無難である。
まとめ
「最善の名前とは、誤解されない名前である。」という定義が印象に残りました。名前が長くなるのは個人的には見づらくなってあまり好きではないですが、誤解されるよりはたしかにいいと思うので、誤解されない名前を心がけてコーディングをしていきたいと思いました。