アクセサの指定をする
attr_accessorなどを指定するとインスタンス変数に外部からアクセスできるようになる、ということはわかりました。しかし、これは一体、どういう働きをしているのでしょうか。
実をいえば、アクセサを指定する文は、指定したインスタンス変数にアクセスするためのメソッドを自動生成していたのです。先のサンプルで、
attr_accessor:nameという指定を用意していましたが、これは以下のようなメソッドをクラスに追加しても全く同じ働きをすることがわかるはずです。
def name
return @name
end
def name=(str)
@name = str
end
最初の
nameメソッドはわかりますね。インスタンスの
nameを指定すれば、
@nameの値が返される。ということは、例えば、
str = obj.nameというようにnameを指定してそのまま
@nameの値が取り出せるようになるわけです。
その後のメソッドはちょっと不思議な感じがします。
def name=(str)という形で定義されています。メソッド名にイコール記号がついているのは不思議な気がしますが、こうしたメソッドもRubyでは使えるんです。これは、「
○○.name = 値」というようにして呼び出されるメソッド、ということになります。例えば、
obj.name = "hoge"
こんな具合にすることで、
objの
@nameに値を設定できる、ということになります。これが、
attr_accessorで行なっていることだったのです。
attr_accessorだけでなく、
attr_readerや
attr_writerも基本的には同じです。
Rubyでは「インスタンス変数へのアクセスは、それを行うメソッドを用意して対応する」という基本原則は変わりません。ですから、上記のようなメソッドを自分で書いて対応させることもできます。自分でメソッドを書いた場合、そこで設定する値などを自由に処理できます。
自動生成されるメソッドは、ただ値をそのまま取り出したり変更したりするだけですので、値を制御することはできません。より柔軟なインスタンス変数への対処を考えるなら、
attr_accessorなどを用いず、自分でアクセスするメソッドを定義したほうが良いでしょう。