難解で簡潔なattr_accessorについてまとめてみた。

Ruby初学者のものです。



**attr_accessorについてまとめてみました。**


railsチュートリアルなどでチラホラ出てきましたが、放置していました。
> プロを目指す人のRuby入門

で本日再度遭遇したので、この機会にきちんと理解しようと思い記事にした次第です。

```ruby:attr_accessor
class Bird
 attr_accessor :name
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```

初めて上記のコードを見たとき、かなりちんぷんかんぷんでした。
「クラスを定義したけどメソッド？がなくて、クラスの中身薄！！！」
「bird = Bird.newで、オブジェクトを作ったのはわかるけど、nameメソッドって定義されてなくない？』
といった具合でした。

attr_accessorに至る背景を知らなかったので、当然といえば当然ですが、初見の理解度はこの程度でした。

**この難解で簡潔なコードを、順を追ってみたいと思います。**

#attr_accessorに至るまで

##reader :nameとattr_wrter:nameに分けられる

**まず、attr_accessorはattr_reader :nameとattr_wrter:nameの2つから成り立っていることを知りました。**

```ruby:attr_readerとattr_writer

class Bird

#attr_accessorと同義です。
attr_reader :name
attr_writer :name
end
```

attr_accessorはattr_readerとattr_writerに分けられるとわかったけど、
それぞれが何を意味しているのかが、不明なのでひとつずつ見ていきます。

##attr_reader

```ruby:attr_readerに置き換える前
class Bird
 def name
  @name 
 end
 def name=(text)
  @name = text
 end
 
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```

上記のようなプログラムがあったとします。


```ruby:attr_reader
def name
  @name 
 end
```
**attr_readerにあたるのは、この3行です。**
@で始まるインスタンス変数を、戻り値とするメソッドですね。
attr_reader :nameの:nameにあたる部分には、上記の3行のメソッド内のインスタンス変数（今回で言うと@name）の@をとり、シンボルの形としてセットします。

```
#インスタンス変数から@をとり、シンボルで書く
@name => :name　=> attr_reader :name 
```

```ruby:attr_readerに置き換えた後
class Bird
 attr_reader :name

 def name=(text)
  @name = text
 end
 
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```



##attr_writer

```ruby:attr_writerに置き換える前
class Bird

 #attr_reader :nameにあたる部分
 def name
  @name 
 end

 def name=(text)
  @name = text
 end 
 
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"

```

予想がついたかもしれませんが、**以下の3行にあたる部分がattr_writer :name**です。

```ruby:attr_writer
def name=(text)
  @name = text
 end
```
インスタンス変数に代入するメソッドですね。　
ここで注意したいのがname = (text)ではなく、name=(text)と、nameと=の間に、空白がないことです。**"name="で1つのメソッド名**です。


```
#メソッド名はインスタンス変数から@をとり=を後ろに置く
@name => name=
```

attr_readerの時と同様に、attr_writer :nameの:nameにあたる部分には、上記の3行のメソッド内のインスタンス変数（今回で言うと@name）の@をとり、シンボルの形としてセットします。



書き換えると以下になります。

```ruby:attr_writerに置き換えた後
class Bird

 def name
  @name 
 end
 
 attr_writer :name
  
end
```

##attr_readerとattr_writerをどちらも置き換えてみる

```ruby:置き換え前
class Bird
 
 #attr_reader :nameに置き換えられる
 def name
  @name 
 end

 #attr_writer :nameに置き換えられる
 def name=(text)
  @name = text
 end
 
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```

```ruby:置き換え後
class Bird
 attr_reader :name 
 attr_writer :name
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```

クラス内のコードが8行から、4行になり、かなりシンプルで見やすくなった。

##attr_accessorに至る
```ruby:attr_accessor
class Bird

 #attr_reader :name とattr_writer :nameを合わせる
 attr_accessor :name
end

bird = Bird.new
bird.name = "そらじろう"
p bird.name #=> "そらじろう"
```


さらに短くなりました。難解で意味不明なコードの意味がじわじわわかり簡潔にまとまりました。


#まとめ

* **attr_accessorは、attr_readerとattr_writerからなる。**
* **attr_readerは、3行からなるインスタンス変数を戻り値とするメソッドを置き換えたメソッド。**
* **attr_writerは、3行からなるインスタンス変数へ代入するメソッドを置き換えたメソッド。**


熟練者の人ほど、コードが簡潔という話をよく聞きますが、今回のattr_accessorのように短いコード裏には、それに至るまでの背景が存在するので、駆け出しのうちは、こういった短いコードの背景を理解することに注力することが大事だなと感じました。

また、こういったコードに出会した際にはQiitaやBoost Noteにまとめて理解を深めていきたいですね。



>[ゼロからわかるRuby超入門](https://gihyo.jp/book/2018/978-4-297-10123-7)