Rubyの初心者ですが、どーもアクセサメソッドに関して附に落ちなかったのですが、ようやく理解できたので噛み砕いてご紹介。
※表現の仕方に不備があれば教えて下さいm(_ _)m
まずアクセサメソッドには3つの種類があります。
attr_reader #rede(読む)
attr_writer #write(書く)
attr_accessor #access(読むと書くの両方)
それでは一つづつ見ていきましょう。
#attr_reader
まずは読むためのアクセサメソッドです。
Productというclassを作って、商品名(name)を作成して、商品名を表示させます。
class Product
def initialize(name)
@name = name
end
end
product = Product.new('pen')
puts product.name
#=> ndefined method `name' for #<Product:0x007fa59b0dc620 @name="pen"> (NoMethodError)
これだけではエラーになります。
Product
というclassを作って、initialize
で@nameインスタンス変数に代入しています。
product = Product.new('pen')
でインスタンスを作成し、product
という変数にインスタンスを代入。
puts product.name
でpenと表示させようとしましたがエラー。
rubyではそのままだとインスタンス変数にアクセスできないのです。
では表示させるためのインスタンスメソッドを作成してみましょう。
class Product
def initialize(name)
@name = name
end
def name
@name
end
end
product = Product.new('pen')
puts product.name
#=>pen
無事に表示させることができました。
しかし、表示させるためだけのメソッドを毎回作成するのは面倒ですよね。。。
そこで登場するのがattr_reader
です。
class Product
attr_reader :name
def initialize(name)
@name = name
end
end
product = Product.new('pen')
puts product.name
#=>pen
これでわざわざ表示させるためのメソッドを作成する必要がなくなりました。
これで簡単にインスタンス変数をread、読む事ができました。
#attr_writer
attr_readerが理解できれば簡単です。
インスタンス変数を変更できるよう(write,書く)になります。
まずはattr_writer
を使わない場合はわざわざそのためのメソッドを作らなければなりません。
class Product
attr_reader :name
def initialize(name)
@name = name
end
def name=(value)
@name = value
end
end
product = Product.new('pen')
product.name = 'note'
puts product.name
#=>none
これも面倒ですよね。
attr_writer
で一発解決。
class Product
attr_reader :name
attr_writer :name
def initialize(name)
@name = name
end
end
product = Product.new('pen')
product.name = 'note'
puts product.name
#=>none
#attr_accessor
attr_reader
とattr_writer
の両方の役割を果たすのがattr_accessor
。
attr_reader
とattr_writer
の意味がわかれば簡単ですね。
class Product
attr_accessor :name
def initialize(name)
@name = name
end
end
product = Product.new('pen')
product.name = 'note'
puts product.name
#=>none
#引っかかってた点と、まとめ
class User
def initialize(name)
@name = name
end
def hello
"Heloo, I am #{@name}"
end
end
user = User.new('atsushi')
p user.hello
#=> Heloo, I am atsushi
例えば上記の様なコードがあるときに、なんでこの場合はアクセサメソッドいらないの?
なんで?
attr_reader
いるんじゃないの?
だってインスタンス変数を参照してるじゃん。
と思っていましたが、違います。
なぜならhelloメソッドで直接インスタンス変数を参照しているからです。
だからアクセサメソッドは必要ありません。
class User
attr_reader :name
def initialize(name)
@name = name
end
end
user = User.new('atsushi')
p user.name
しかし上記のような場合はattr_reader :name
が必要です。
なぜなら、user = User.new('atsushi')
はuserにインスタンスを代入しています。
userという変数からインスタンス変数を参照する必要があるため、アクセサメソッドが必要なわけです。
クラスの外部からインスタンス変数の参照するために必要なのです。
アクセサメソッドは、外部インスタンスのインスタンス変数を参照したり変更するために定義する。
というところでしょうか。
さぁまだまだ初心者なのでがんばります。