LoginSignup
150
117

More than 5 years have passed since last update.

Rubyのattr_accessor等について

Last updated at Posted at 2015-10-24

Rubyのattr_accessorattr_reader, attr_writer等が良く分からなくて,モヤモヤしていたので,調べて自分なりに納得したことをまとめておく.

例として以下のコードを考える.

class Triangle
  attr_accessor :baseLength, :height

  def initialize(baseLength, height)
    @baseLength = baseLength
    @height = height
  end
end

sankaku = Triangle.new(10.0, 3.0)
puts sankaku.baseLength
puts sankaku.height

クラスの定義の中で

attr_accessor :baseLength

のように書くとクラスのインスタンス変数@baseLength

sankaku.baseLength

のようにアクセス可能になる.ここで個人的に気持ち悪かったのは,インスタンス変数名は@で始まるから

sankaku.@baseLength

とアクセスするようにしてもよさそうなのにそうなっていないこと.あと,

attr_accessor :baseLength

がインスタンス変数を外からアクセス可能にするための記述だというのなら,なぜ

attr_accessor @baseLength

のように記述しないのだろう?

まぁそれがRubyの仕様だと言ってしまえばそれまでだけど,,,,

いろいろ調べて,「まつもと直伝 プログラミングのオキテ 第6回」が一番腑に落ちた.これによると,

 attr_accessorは内部的に次のような処理を行っています。

(1)引数のシンボルすべてに対して以下の処理を繰り返す。

(2)シンボルで指定された名前のメソッドを定義する。そのメソッドはシンボルの名前の先頭に「@」を付加したインスタンス変数の値を取り出す。

(3)シンボルで指定されたメソッド名の後ろに「=」を付加した名前のメソッドを定義する。そのメソッドは引数を1つ取り,その値をシンボルの名前の先頭に「@」を付加したインスタンス変数に設定する。

とある.これから分かるのは,まず

sankaku.baseLength

baseLengthはインスタンス変数ではなくインスタンス変数@baseLengthの値を返してくれるメソッドだということです.これで最初の私のモヤモヤ感は解消しました.

また2番目の気持ち悪さも,

attr_accessor :baseLength

という記述は,インスタンス変数を外からアクセス可能にする,ということをやっているのではないということですから,解消されます.つまりこの baseLength はインスタンス変数 @baseLength を意味しているのではなく,メソッドの名前なのだから @ が付かなくて当然です.

150
117
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
150
117