controllerのインスタンス変数をなんでviewでも使えるの？

## はじめに
Railsでは```controller```で定義したインスタンス変数を```view```側で使うことができますが、最近、ふと「これなんで？」と思ったのでrailsの中身を見てみようと思います。

## コードリーディング
作成される```controller```は```ApplicationController```を継承していて、```ApplicationController```は```ActionController::Base```を継承しているので、```ActionController::Base```を見にいきます。

```actionpack/lib/action_controller/base.rb
# == Renders
  #
  # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
  # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured.
  # The controller passes objects to the view by assigning instance variables:
  #
  #   def show
  #     @post = Post.find(params[:id])
  #   end
  #
  # Which are then automatically available to the view:
  #
  #   Title: <%= @post.title %>
  #
  # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
  # will use the manual rendering methods:
  #
  #   def search
  #     @results = Search.find(params[:query])
  #     case @results.count
  #       when 0 then render action: "no_results"
  #       when 1 then render action: "show"
  #       when 2..10 then render action: "show_many"
  #     end
  #   end
  #
  # Read more about writing ERB and Builder templates in ActionView::Base.
```
>The controller passes objects to the view by assigning instance variables:

```instance variable```を```assign```することで、```controller```は```view```側にオブジェクトを渡すと書かれています。
まさにこのことです。

>Read more about writing ERB and Builder templates in ActionView::Base.

もっと知りたかったら```ActionView::Base```を見に行けと書かれているので見にいきます。

```actionview/lib/action_view/base.rb
    def initialize(lookup_context, assigns, controller) # :nodoc:
        @_config = ActiveSupport::InheritableOptions.new
        
        @lookup_context = lookup_context
        
        @view_renderer = ActionView::Renderer.new @lookup_context
        @current_template = nil
        
        assign(assigns)
        assign_controller(controller)
        _prepare_context
    end
```
```ActionView::Base```クラスのインスタンスが生成されるときの処理内容です。
```actionview/lib/action_view/base.rb
    def assign(new_assigns) # :nodoc:
        @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
    end
```
今回対象となるのは```assign```メソッドです。(ここはエスパーしました。)
```ActionView::Base```のインスタンス変数```@_assigns```に、```ActionView::Base```が```initialize```された際の引数```assigns```を代入しています。
次は```ActionView::Base```が```initialize```されるところを見にいきます。

https://docs.ruby-lang.org/ja/latest/method/Object/i/instance_variable_set.html

```actionview/lib/action_view/rendering.rb
    def view_context
        view_context_class.new(lookup_context, view_assigns, self)
    end
```
```ActionView::Base```は```view_context```メソッドによって、```initialize```されます。(ここはまた別の記事で書きます。)
```view_context```メソッドはそのすぐ下にある```_render_template```メソッドから呼び出されていて、このメソッドはレスポンスのbodyを作るメソッドです。
```view_context```に渡される第2引数が```assign```メソッドに渡される引数(view側で使うことができるインスタンス変数)です。

```view_assigns```メソッドを見にいきます。
```actionpack/lib/abstract_controller/rendering.rb
    def view_assigns
      variables = instance_variables - _protected_ivars

      variables.each_with_object({}) do |name, hash|
        hash[name.slice(1, name.length)] = instance_variable_get(name)
      end
    end
```
```view_assigns```メソッドは最終的に変数```variables```を返しますが、その中身は```instance_variables```で、これはRuby由来のメソッドでその呼び出し元のオブジェクトのインスタンス変数を返すメソッドです。

https://docs.ruby-lang.org/ja/latest/method/Object/i/instance_variables.html

このときの呼び出し元のオブジェクトは```controller```のインスタンスなので、```controller```で定義したインスタンス変数がそれにあたります。
ここで```controller```のインスタンス変数が```view```側に渡されています。

## 参考にしたサイト

http://railscasts.com/episodes/397-action-view-walkthrough?view=asciicast

https://api.rubyonrails.org/files/actionpack/README_rdoc.html