SakuraWi - BLog

WEBエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

インスタンス変数の理解【Ruby】


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 のように置いてあげればいい、ということですね。