ゲッター、セッターについて

# 概要
Rubyにおけるゲッター、セッターについてまとめてみました。

# ゲッター
通常インスタンス変数は、定義されているクラス内でしか参照することができず、クラス外からはアクセスすることができません。

```Ruby:Item.rb
class Item
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end
end

apple = Item.new(120, 5)
# => Itemクラスからappleオブジェクト（インスタンス）を生成したが、このままだとinitializeメソッドで初期化したインスタンス変数、 @price と @quantity を利用することができない
```
そこでゲッターを用意します。
ゲッターは、クラスに設定したインスタンス変数の値を、インスタンスから読み取って表示するためだけに定義するメソッドです。

```Ruby:Item.rb
class Item
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def price # ゲッター
    @price
  end

  def quantity # ゲッター
    @quantity
  end
end

apple = Item.new(120, 5)
p apple.price # => 120
p apple.quantity # => 5
```
そのインスタンス変数が定義されているオブジェクト（今回の場合、apple）をレシーバオブジェクトとして、メソッドを呼び出すことでインスタンス変数にアクセスし、その情報を利用することができます。

# セッター
セッターとは、あるオブジェクトが持つインスタンス変数の値を更新するためだけのメソッドのことです。
通常、インスタンス変数の値をクラス外から更新することはできません。

```Ruby:Item.rb
class Item
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def price # ゲッター
    @price
  end

  def quantity # ゲッター
    @quantity
  end
end

apple = Item.new(120, 5)

# appleの価格を150にしようとしたが、エラーが出た
apple.price = 150 # => undefined method `price=' for #<Item:0x0000000002439d18 @price=120, @quantity=5> (NoMethodError)
```
そこでセッターを用意します。

```Ruby:Item.rb
class Item
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def price # ゲッター
    @price
  end

  def quantity # ゲッター
    @quantity
  end

  def price=(price) # セッター
    @price = price
  end

  def quantity=(quantity) # セッター
    @quantity = quantity
  end
end

apple = Item.new(120, 5)

apple.price = 150 # appleの価格を更新
apple.quantity = 10 # appleの個数を更新 

p apple.price # => 150
p apple.quantity # => 10
```

セッターの記述は少し特殊ですが、Rubyではあたかも変数代入かのようにセッターを利用するのが慣例となっています。


# ゲッターとセッターを定義してくれる便利なメソッド
もっと簡易的にゲッターとセッターを定義してくれるメソッドが以下3種類です。

* attr_reader（ゲッター）
* attr_writer（セッター）
* attr_accessor（ゲッターとセッター）

一つずつ見ていきます。
## attr_reader
attr_readerは、記述したクラスにゲッターを定義してくれるメソッドです。インスタンス変数のクラス外からの参照を可能にします。

**`attr_reader :変数名`**

```Ruby:Item.rb
class Item
  attr_reader :price
  attr_reader :quantity

  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end
end

apple = Item.new(120, 5)
p apple.price # => 120
p apple.quantity # => 5
```

## attr_writer
attr_writerは、記述したクラスにセッターを定義してくれるメソッドです。インスタンス変数のクラス外からの更新を可能にします。

**`attr_writer :変数名`**

```Ruby:Item.rb
class Item
  attr_reader :price
  attr_reader :quantity
  attr_writer :price
  attr_writer :quantity

  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end
end

apple = Item.new(120, 5)

apple.price = 150 # appleの価格を更新
apple.quantity = 10 # appleの個数を更新 

p apple.price # => 150
p apple.quantity # => 10
```

## attr_accessor
attr_readerは、attr_readerとattr_writerの両方の機能を一つにまとめたメソッドです。記述したクラスにゲッターとセッターを定義し、インスタンス変数のクラス外からの参照と更新を可能にします。

**`attr_accessor :変数名`**

```Ruby:Item.rb
class Item
  attr_accessor :price
  attr_accessor :quantity

  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end
end

apple = Item.new(120, 5)

apple.price = 150 # appleの価格を更新
apple.quantity = 10 # appleの個数を更新 

p apple.price # => 150
p apple.quantity # => 10
```

# アクセッサーとは
これまで、attr_accessorのことをアクセッサーと呼ぶと認識していましたが、正確にはゲッターやセッターの総称のことを意味する言葉だそうです。
以下、公式リファレンスからの引用です。
>オブジェクトの特定のインスタンス変数について、その値を読み出すメソッドとその値を設定するメソッドの総称。
メソッド名はインスタンス変数の識別子と同じものを使う習慣がある。例えば @foo の値を読み出すメソッドは foo とし、@foo に値を設定するメソッドは foo= とする。

参考：Ruby 3.0.0 リファレンスマニュアル
https://docs.ruby-lang.org/ja/3.0.0/doc/glossary.html#a


# 参考

* https://terakura-aina.hatenablog.com/entry/2020/12/15/%E3%80%90Ruby%E3%80%91%E3%82%B2%E3%83%83%E3%82%BF%E3%83%BC/%E3%82%BB%E3%83%83%E3%82%BF%E3%83%BC%E3%81%A8%E3%81%AF