ムカデノワラジ

ムカデノワラジ

ガジェット・Webサービス・プログラミング・エンタメについて書く雑記ブログ

MENU

Rubyのclassでなぜattr_accessor使うのか:使い道について考えてみる。

Userクラスを使ってattr_accessorを考える

次のようなクラスがあるとする。

class User
end
@nameを持つとき

このユーザーに名前のプロパティを持たせたいとき
次のような例が考えられる。

class User
  def initialize(name)
    @name = name
  end
end

taro=User.new()
taro.name
#=> "taro"
@nameを変更するには?

このUserクラスの問題点

  • taroの名前を変えたいときどうするか

直感的に書くと

taro.name="jiro"

これはエラーになる

ArgumentError: wrong number of arguments (given 1, expected 0 )

このままではインスタンス変数を直接変更することはできない。

次に思いつくのがnameメソッドを新たに定義すること

class User
  def initialize(name)
    @name = name
  end
  def name(arg=@name)
    @name = arg
  end
hanako=User.new("suzuki hanako")
hanako.name #=> "suzuki hanako"
hanako.name("satoh hanako") #=> hanako.name="satoh hanako"

こうすれば.nameで@nameを返し、name()にパラメタが与えられたときは名前を変更することはできる。

  • 外部から操作したい変数が増えるたびにメソッドを追加しないといけない。
  • つまり 変数とメソッドの両方が必要になる
  • hanako.name="xxx"と比べて直感的じゃない。
  • 冗長
attr_accessorを使ってスマートに書く
class User
  attr_accessor :name

#  def initialize(name)
#    @name = name
#  end
end
# satoshi = User.new("satoshi")
satoshi.name  #=> nil

satoshi.name="satoshi"
satoshi.name #=> "satoshi"

ちなみにattr_readerを使うと参照は可能、変更は不可

class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end
someone= User.new("Sam")
someone.name #=> Sam
someone.name="Someone"
#=> NoMethodError

ポイント

一時的な(すべてのインスタンスに対して必要なわけではない)プロパティを定義したいとき、あるいは外部から変更したり参照したりしたいプロパティを扱うとき、たとえばRailsでレコードに保存しない情報をモデルに紐づけて扱うときに使える。