今回のエントリでは先日、僕が勤めているソニックガーデンで話題になったプログラミング関連の小ネタを書きます。
それは何かというと、「プログラミング初心者は変数名やメソッド名を略さない方がいい」という話です。
長い変数名やメソッド名はつい略したくなります。
実際、僕も長い名前を略すときはよくあります。
ですが、略称を使うのは長年の経験から「この略称は一般的だから誤解を招くことはきっと少ないだろう」とか「前後の文脈から、変数の中身は誰が見ても明らかだろう」という想像が付いた場合だけです。
一方、プログラミング初心者の人は経験が浅いため、「一般的かどうか」とか、「誤解が発生しないかどうか」といった判断ができません。
そのため、他の人が見たときに「え、何この変数名?」と思ってしまうような略称を付けてしまう恐れがあります。
たとえば、先日のコードレビューで、初心者の人がrev_no
という名前の変数を定義していました。
この変数名を見て、みなさんは何が格納される変数かわかりますか?
僕は「revison_number
の略かな?」と思いました。
でも、初心者の人に聞いたら、「それはreverse_number
(逆順の数字)の略だ」という答えが返ってきました。
はい、しっかり誤解が発生してますね!!
ですから、プログラミング初心者の人は変数名やメソッド名を略さないようにしましょう。
略すのは先輩プログラマからOKをもらったときだけにしてください。
さきほどの例ならrev_no
ではなく、reverse_number
と略さずに書くべきです。
(正確にはreversed
のように過去分詞形にしたいところですが)
ちょっと厳しいルールかもしれませんが、初心者のうちは変な悪い癖が付いてしまうことを避ける方が重要なので、こういったルールには意味があると思います。
追記:「でも長い名前は入力するのが大変なんです!」という方へ
長い名前を略したい一番の動機は、「タイピング量を減らしたいから」だと思います。
この点についてはエディタやIDEの機能を活用しましょう。
たとえば、VimであればCtrl-NやCtrl-Pでバッファ内に表示されている文字列を自動補完することができます。
Visual Studio Code(VS Code)やRubyMineなどのIDEでも、途中まで変数名をタイプすると変数やメソッドの候補を表示してくれます。
ですので、「タイプ量を減らしたいから、名前を略す」のではなく、「タイプ量を減らすためにエディタやIDEの操作を勉強する」と考えるようにしましょう。
その方がずっと生産的です!
追記2:reverse_no
ならOKですか?
「reverse_number
ではなく、reverse_no
ならOKか?」という点についても議論してみましょう。
たしかに"number"を"no"と略すのはプログラミングに限らず、日常生活でもよく見かけるので、一般的な略称と言えるかもしれません。
ですが、以下の点で"no"は"number"よりも問題が起きやすい名前だと僕は考えます。
- "yes/no"の"no"と混同しやすい
- 配列に格納する場合などに複数形を使おうとすると"nos"や"noes"になるが(参考)、複数形になると急に馴染みが薄くなる("no"の複数形であることがぱっと理解しづらい)
よって、何か特別な理由がない限り、"no"ではなく"number"を使う方が望ましいと考えます。
追記3:略していいケースってどんなケース?
上の本文で「実際、僕も長い名前を略すときはよくあります」と書きましたが、具体例がないとイメージが沸きにくいと思うので例をいくつか挙げておきます。
たとえば、以下のような単語は他のコードでも省略形をよく見かけるので、省略して書く場合があります。
- execute = exec
- initialize = init
- calculate = calc
- character = char
- arguments = args
寿命が短いローカル変数や仮引数に対しては以下のような名前を付ける場合があります。
- average = avg
- maximum / minimum = max / min
- message = msg
- exception = e または ex
- event = e
単純なループの変数に対しては以下のような略称を付けることがあります。
- 文字列の場合 = s または str(stringの略)
- 文字の場合 = c(characterの略)
- 数値の場合 = i(integerの略)または n(numberの略)
- ファイルオブジェクトの場合 = f (fileの略)
# ループの変数名をiとする場合のコード例 [1, 2, 3].map do |i| i * 10 end
寿命が極めて短い変数に対してはクラス名の頭文字を使う場合があります。
# Userクラスのインスタンスを配列に格納 users = User.all # ブロック内の変数の寿命が極めて短いので、名前をuとする users.map { |u| u.name.upcase }
ですが、寿命がそれなり長い場合は略さずに書きます。
# 寿命がそれなりに長いので略さずにuserとする users.map do |user| books = find_books(user) cars = find_cars(user) "#{user.name} has #{books.size} books and #{cars.size} cars" end
なお、母音を引っこ抜いたようなオレオレルールな略称はわかりづらくなるだけなので、絶対に使いません。
# こんな略称は絶対書かない gbsn_gtrs = Guitar.brand('gibson') fndr_gtrs = Guitar.brand('fender') # 変数名は略さずに書きます gibson_guitars = Guitar.brand('gibson') fender_guitars = Guitar.brand('fender')
他にも略称を使うパターン、使わないパターンがあるかもしれませんが、ぱっと思いつくのはこんな感じです。
追記4:無味無臭な名前も避ける
略称とはちょっと異なりますが、こういう変数名もダメな部類に入ります。
data
info
item
element
obj
array
(ary
,arr
)list
こういう変数名を僕は「無味無臭な名前」と呼んでます。
プログラムに出てくる変数は全て何らかのデータなので、dataなんて名前を付けてないの同じです(他の変数名も同様)。
中身が想像できる名前を付けるようにしましょう。
より詳しい説明と具体的な改善方法は、こちらのブログを読むと参考になります(ちょっと言い方が激しいですが😅)。
data とか info とか list とか item とかいう変数名止めろ - Neo's World
20年近くプログラミングをやってても、命名にはすごく時間がかかります。
熟練者でも時間がかかるんだから、プログラミング初心者が横着して雑な名前を付けてはいけないのはなおさらです!
プログラミングで一番長い時間悩むのが「いい名前を考える時間」かもしれない。
— Junichi Ito (伊藤淳一) (@jnchito) 2020年7月9日
ロジックを考えたりコードを書いたりする時間はスキルの向上とともにどんどん速くなってくるけど、適切な名前(クラス名、メソッド名、変数名etc)を考えるスピードはコードを書くスピードほど速くならないんだよねえ。