give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

プログラミング初心者は変数名やメソッド名を略さない方がいいよ、という話

今回のエントリでは先日、僕が勤めているソニックガーデンで話題になったプログラミング関連の小ネタを書きます。
それは何かというと、「プログラミング初心者は変数名やメソッド名を略さない方がいい」という話です。

長い変数名やメソッド名はつい略したくなります。
実際、僕も長い名前を略すときはよくあります。
ですが、略称を使うのは長年の経験から「この略称は一般的だから誤解を招くことはきっと少ないだろう」とか「前後の文脈から、変数の中身は誰が見ても明らかだろう」という想像が付いた場合だけです。

一方、プログラミング初心者の人は経験が浅いため、「一般的かどうか」とか、「誤解が発生しないかどうか」といった判断ができません。
そのため、他の人が見たときに「え、何この変数名?」と思ってしまうような略称を付けてしまう恐れがあります。

たとえば、先日のコードレビューで、初心者の人がrev_noという名前の変数を定義していました。
この変数名を見て、みなさんは何が格納される変数かわかりますか?
僕は「revison_numberの略かな?」と思いました。
でも、初心者の人に聞いたら、「それはreverse_number(逆順の数字)の略だ」という答えが返ってきました。
はい、しっかり誤解が発生してますね!!

ですから、プログラミング初心者の人は変数名やメソッド名を略さないようにしましょう。
略すのは先輩プログラマからOKをもらったときだけにしてください。

さきほどの例ならrev_noではなく、reverse_numberと略さずに書くべきです。
(正確にはreversedのように過去分詞形にしたいところですが)

ちょっと厳しいルールかもしれませんが、初心者のうちは変な悪い癖が付いてしまうことを避ける方が重要なので、こういったルールには意味があると思います。

追記:「でも長い名前は入力するのが大変なんです!」という方へ

長い名前を略したい一番の動機は、「タイピング量を減らしたいから」だと思います。
この点についてはエディタやIDEの機能を活用しましょう。

たとえば、VimであればCtrl-NやCtrl-Pでバッファ内に表示されている文字列を自動補完することができます。

f:id:JunichiIto:20201020141852g:plain:w500

Visual Studio Code(VS Code)やRubyMineなどのIDEでも、途中まで変数名をタイプすると変数やメソッドの候補を表示してくれます。

f:id:JunichiIto:20201020142315g:plain:w500

ですので、「タイプ量を減らしたいから、名前を略す」のではなく、「タイプ量を減らすためにエディタや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

寿命が短いローカル変数や仮引数に対しては以下のような名前を付ける場合があります。

  • average = avg
  • message = msg
  • exception = e または ex
  • event = e

単純なループの変数に対しては以下のような略称を付けることがあります。

  • 文字列の場合 = s または str(stringの略)
  • 文字の場合 = c(characterの略)
  • 数値の場合 = i(integerの略)または n(numberの略)
# ループの変数名を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')

他にも略称を使うパターン、使わないパターンがあるかもしれませんが、ぱっと思いつくのはこんな感じです。