はじめに
- プログラミングをしていると、日々変数名をつけるという作業をします。自分が書いたコードや他の方が書かれたコードを読むにあたり、変数名を正しくつけることで理解しやすくなった経験があるので、改めてここで整理してみます
- Rubyの場合特に型を明示的に記述しないので、静的型付け言語に比べて変数名というのはコードの読みやすさの大事な要素になってくると考えています。認識の齟齬が生まれにくような変数名にすることで開発生産性向上に寄与できれば幸いです
変数名はインスタンスのクラス名を小文字にしたものを用いる
- Rubyは型を明示的に書かないので、変数にどの型のものが入っているかが分かりにくいことがあります。そのため、基本的にはインスタンスのクラス名を小文字にしたものを変数名として用いるのが良いと思います
# 良い例
cart = Cart.new
cart = user.carts.new
electric_plan = ElectircPlan.new
# 悪い例
basket = Cart.new # cartのことをbasketに言い換えてしまっている
plan = ElectricPlan.new # electricを省略してしまっている
配列の場合は複数形にする
- 単数のままだと一つのインスタンスなのか配列なのかわからないため、配列(
ActiveRecord::Relation
を含む)の場合、複数形にして、一つではないことを明示的になるようにします
# 良い例
carts = Cart.all
# 悪い例
cart = Cart.all
スコープが狭い場合は、省略することも許容する
- 短い変数名を好ましくないと思う開発者は一定数います。しかし、golangでは、狭いスコープでは、短い変数名を使うことが好ましいとされています1。私はRuby on Railsでの開発の際でも、スコープが狭くて、その変数に入ってくる型が明らかな場合は省略した変数名も許容して良いと考えています
- 例えば、ブロックの変数など、スコープが明確になっている場合は、変数名を省略することも許容してよいと考えています。例えば以下の例のように数行以内であれば、
ep
がどのクラスのインスタンスなのかは判断できます。ブロック内で毎回electric_plan
と記載して量が増えるよりは読みやすいです - 一方、クラス内でつかうインスタンス変数名や、getterの変数名は、変数のスコープが広い(局所化されていない)ため、省略して
ep
としてしまうと、意味が分かりにくくなるため、省略した変数名は望ましくありません - とはいえ、個人的に許容しているというものなので、既存のプロジェクトの方針で、省略を許容しない場合は、私も省略せずに実装します。実装される方は、参画プロジェクトの方針に従ってください
# 省略した変数名を許容してもよい例
ElectricPlan.all.each do |ep|
ep.update!(some_column: some_value)
end
# 省略した変数名を許容しない例
class SomeRubyClass
attr_accessor :ep
def initialize(electirc_plan)
self.ep = electric_plan
end
end
# スコープが広い場合は省略せずに変数名を定義するべき
class SomeRubyClass
attr_accessor :electric_plan
def initialize(electirc_plan)
self.electirc_plan = electric_plan
end
end
変数に格納される型が複数ありうる場合はそれがわかる変数名にする
- Rubyは型が柔軟ですが、変数名は型が想起できる変数名をつけるべきだと考えています。一方で、複数の型が入ってくるのを許容したい場合はそれが明示的になるような変数名にするべきです
- 下記の例では、
some_scope
の引数はArea
のインスタンスか、そのid
が渡されることが期待されているので、area_or_area_id
という引数名にしたいところです
class SomeClass < ApplicationRecord
belongs_to :area
# 悪い例
scope :some_scope, ->(area) {
area_id = area.is_a?(Area) ? area.id : area
where(area_id:)
}
# 良い例
scope :some_scope, ->(area_or_area_id) {
area_id = area_or_area_id.is_a?(Area) ? area_id : area_or_area_id.id
# NOTE: あえてarea_idにしなくても、where(area: area_or_area_id)でもよしなに処理してくれる
where(area_id:)
}
型を想起させる変数名なのに型が違う
- 例えば、次の例では、filesという変数には、
File
型の配列が格納されることが想起されます。しかし、実際には、ファイルのパスのstringです。この場合は、型を想起させない変数名にした方が無難だと思います
# 悪い例
files = Dir.glob(Rails.root.join("spec/*.rb"))
=> ["/Users/hogehoge/spec/rails_helper.rb", "/Users/hogehoge/spec/spec_helper.rb"]
# 良い例
file_paths = Dir.glob(Rails.root.join("spec/*.rb"))
最後に
- Rubyは型を明示的に書く必要がない一方で、型がないわけではなく、実装時には型を意識する必要があります。今回記事を書くにあたりまとめてみて感じたことは、変数名から型を推測できるようにすべきだということです。これはもしかしたら型を明示的に記載しないRubyだから気をつけるべきということになるのかもしれませんが、静的型付け言語であったとしても変数名から型を推測できるように変数名を定義してあげた方が読みやすいと思います。私は仕事でC#を実装することがありますが、IDEが強力なので変数の型というのはすぐに把握できます。しかし、認知負荷を考えるとIDEに頼らずとも型を把握できるのが良いでしょう。従って、本記事で記載したことはRubyに限らず幅広い言語で適用できるのではないかと考えています