protectedでレシーバ付きでメソッドを呼び出す

```rb
irb(main):001* class User
irb(main):002*   attr_reader :name
irb(main):003*
irb(main):004*   def initialize(name, weight)
irb(main):005*     @name = name
irb(main):006*     @weight = weight
irb(main):007*   end
irb(main):008*
irb(main):009*   def heavier_than?(other_user)
irb(main):010*     other_user.weight < @weight
irb(main):011*   end
irb(main):012> end
=> :heavier_than?
irb(main):013> alice = User.new("Alice", 50)
=> #<User:0x0000000106eeb658 @name="Alice", @weight=50>
irb(main):014> bob = User.new("BoB",60)
=> #<User:0x0000000106f1bc90 @name="BoB", @weight=60>
irb(main):015> alice.heavier_than?(bob)
(irb):10:in `heavier_than?': undefined method `weight' for #<User:0x0000000106f1bc90 @name="BoB", @weight=60> (NoMethodError)

    other_user.weight < @weight
              ^^^^^^^
...
```
```rb
irb(main):001* class User
irb(main):002*   attr_reader :name, :weight
irb(main):003*
irb(main):004*   def initialize(name, weight)
irb(main):005*     @name = name
irb(main):006*     @weight = weight
irb(main):007*   end
irb(main):008*
irb(main):009*   def heavier_than?(other_user)
irb(main):010*     other_user.weight < @weight
irb(main):011*   end
irb(main):012> end
=> :heavier_than?
irb(main):013> alice = User.new("Alice", 50)
=> #<User:0x00000001085f3e18 @name="Alice", @weight=50>
irb(main):014> bob = User.new("BoB", 60)
=> #<User:0x0000000108572930 @name="BoB", @weight=60>
irb(main):015> alice.heavier_than?(bob)
=> false
```

* アクセサメソッドで`weight`は読み込みできないようになっている

# protectedメソッド
>`外部には公開したくないが、同じクラスやサブクラスの中であればレシーバ付きで呼び出せるようにしたい`、という時に登場するのがprotectedメソッドです。

### protectedメソッドを試してみる
```rb
irb(main):001* class User
irb(main):002*   attr_reader :name
irb(main):003*
irb(main):004*   def initialize(name, weight)
irb(main):005*     @name = name
irb(main):006*     @weight = weight
irb(main):007*   end
irb(main):008*
irb(main):009*   def heavier_than?(other_user)
irb(main):010*     other_user.weight < @weight
irb(main):011*   end
irb(main):012*
irb(main):013*   protected
irb(main):014*
irb(main):015*   def weight
irb(main):016*     @weight
irb(main):017*   end
irb(main):018> end
=> :weight
irb(main):019> alice = User.new("Alice",50)
=> #<User:0x0000000103de9168 @name="Alice", @weight=50>
irb(main):020> bob = User.new("Bob", 60)
=> #<User:0x00000001003c3178 @name="Bob", @weight=60>
irb(main):021> alice.heavier_than?(bob)
=> false
irb(main):022> bob.heavier_than?(alice)
=> true
irb(main):023> alice.weight
(irb):23:in `<main>': protected method `weight' called for #<User:0x0000000103de9168 @name="Alice", @weight=50> (NoMethodError)

alice.weight
     ^^^^^^^
```

### privateメソッドで上のコードを実行する
```rb
irb(main):001* class User
irb(main):002*   attr_reader :name
irb(main):003*
irb(main):004*   def initialize(name, weight)
irb(main):005*     @name = name
irb(main):006*     @weight = weight
irb(main):007*   end
irb(main):008*
irb(main):009*   def heavier_than?(other_user)
irb(main):010*     other_user.weight < @weight
irb(main):011*   end
irb(main):012*
irb(main):013*   private
irb(main):014*
irb(main):015*   def weight
irb(main):016*     @weight
irb(main):017*   end
irb(main):018> end
=> :weight
irb(main):019> alice = User.new("Alice",50)
=> #<User:0x000000010fae0a78 @name="Alice", @weight=50>
irb(main):020> bob = User.new("Bob", 60)
=> #<User:0x00000001136d9f48 @name="Bob", @weight=60>
irb(main):021> alice.heavier_than?(bob)
(irb):10:in `heavier_than?': private method `weight called for #<User:0x00000001136d9f48 @name="Bob", @weight=60> (NoMethodError)

    other_user.weight < @weight
              ^^^^^^^

...
irb(main):022> bob.heavier_than?(alice)
(irb):10:in `heavier_than?': private method `weight called for #<User:0x000000010fae0a78 @name="Alice", @weight=50> (NoMethodError)

    other_user.weight < @weight
              ^^^^^^^
...
irb(main):023> alice.weight
(irb):23:in `<main>': private method `weight' called for #<User:0x000000010fae0a78 @name="Alice", @weight=50> (NoMethodError)

alice.weight
     ^^^^^^^
```
* privateメソッドweightは読み込めない

# 特定のメソッドをprotectedに指定する
```rb
irb(main):033* class User
irb(main):034*   attr_reader :name, :weight
irb(main):035*   protected :weight
irb(main):036*   def initialize(name, weight)
irb(main):037*     @name = name
irb(main):038*     @weight = weight
irb(main):039*   end
irb(main):040*
irb(main):041*   def heavier_than?(other_user)
irb(main):042*     other_user.weight < @weight
irb(main):043*   end
irb(main):044*
irb(main):045*   def weight
irb(main):046*     @weight
irb(main):047*   end
irb(main):048> end
=> :weight
irb(main):049> alice = User.new("Alice",50)
=> #<User:0x0000000113425ce8 @name="Alice", @weight=50>
irb(main):050> bob = User.new("Bob", 60)
=> #<User:0x00000001134bed30 @name="Bob", @weight=60>
irb(main):051> alice.heavier_than?(bob)
=> false
```

### 上のコードを`attr_reader :name`にしてみると
```rb
irb(main):018* class User
irb(main):019*   attr_reader :name
irb(main):020*   protected :weight
irb(main):021*   def initialize(name, weight)
irb(main):022*     @name = name
irb(main):023*     @weight = weight
irb(main):024*   end
irb(main):025*
irb(main):026*   def heavier_than?(other_user)
irb(main):027*     other_user.weight < @weight
irb(main):028*   end
irb(main):029*
irb(main):030*   def weight
irb(main):031*     @weight
irb(main):032*   end
irb(main):033> end
(irb):20:in `protected': undefined method `weight' for class `User' (NameError)

  protected :weight
  ^^^^^^^^^
```
* アクセサメソッドで読み込まれなければprotectedは使えない

### attr_writerにすると読み込まれないからエラーになる
```rb
irb(main):017* class User
irb(main):018*   attr_writer :name, :weight
irb(main):019*   protected :weight
irb(main):020*   def initialize(name, weight)
irb(main):021*     @name = name
irb(main):022*     @weight = weight
irb(main):023*   end
irb(main):024*
irb(main):025*   def heavier_than?(other_user)
irb(main):026*     other_user.weight < @weight
irb(main):027*   end
irb(main):028*
irb(main):029*   def weight
irb(main):030*     @weight
irb(main):031*   end
irb(main):032> end
(irb):19:in `protected': undefined method `weight' for class `User' (NameError)

  protected :weight
  ^^^^^^^^^
...
irb(main):033* class User
irb(main):034*   attr_reader :name, :weight
irb(main):035*   protected :weight
irb(main):036*   def initialize(name, weight)
irb(main):037*     @name = name
irb(main):038*     @weight = weight
irb(main):039*   end
irb(main):040*
irb(main):041*   def heavier_than?(other_user)
irb(main):042*     other_user.weight < @weight
irb(main):043*   end
irb(main):044*
irb(main):045*   def weight
irb(main):046*     @weight
irb(main):047*   end
irb(main):048> end
=> :lifter: 
````

# 感想
アクセサメソッドがおかしいとprotectedでエラーが起こる。
詳しくは理解していない。

### `weight=`が呼び出されるので`protected :weight=`をするとエラーが出ない
```rb
irb(main):049* class User
irb(main):050*   attr_writer :name, :weight
irb(main):051*   protected :weight=
irb(main):052*   def initialize(name, weight)
irb(main):053*     @name = name
irb(main):054*     @weight = weight
irb(main):055*   end
irb(main):056*
irb(main):057*   def heavier_than?(other_user)
irb(main):058*     other_user.weight < @weight
irb(main):059*   end
irb(main):060*
irb(main):061*   def weight
irb(main):062*     @weight
irb(main):063*   end
irb(main):064> end
=> :weight
```