Ruby,RubyonRailsの学習を始めて、インスタンス変数についていまいち理解していなかったので記事にしました。 インスタンス変数の中身の理解について書いています。
インスタンス変数の実装中身について
疑問点
class MessageFilter def initialize(*words) @ng_words = words end attr_reader :ng_words def detect?(text) @ng_words.any?{|w| text.include?(w) } end end
このコードでなぜattr_readerが必要なのかいまいちわかっていませんでした。
word = MessageFilter.new("aaa") word.ng_word
でいけるんじゃないの?って思ってました。
なんだかいけそうじゃない?
そう、attr_reader
が必要な理由がわかっていませんでした。
インスタンス変数の仕組み
実はインスタンス変数は以下の実装がこっそりとされている、という理解でいいかと思います。
パーフェクトRuby 2章のP52あたりを読むとかなりわかりやすく記載されていました。
class Ruler def length=(val) @length = val end def length @length end # 上記の二つは実際には attr_accessor length # と定義するのと同義 end
上記の場合において、
ruler = Ruler.new(125) ruler.length
とするとどうなるでしょう?
そう、.length
で値を参照することができます。
そうそう、これこれ、なんて思っていた変数的な処理ですね。
なんだかやっぱり、word.ng_word
でもいけそうなんじゃないかって気がします。
ですが、よく考えると、word.ng_word
とするには、上記のようなメソッドの記述が本当は必要なのです。
でもこれは当たり前のように使いたい、もっと便利にしようと思って簡単に記述できるようになっているのです!
上記のlength
のメソッド記述の省略の形がattr_accessor
になっているのです。
attr_reader
と attr_writer
については書き込み限定だったり、読み出し限定のものとして用意されています。
まとめ
インスタンス変数にアクセスさせるためには、上記のような実装か
attr_accessor
のような記述が必要。
簡単な解釈とするなら、インスタンスで便利な変数の記述するには、
attr_accessor :value
のように置いてあげればいい、ということですね。