Railsの変数のアットマークとドルマーク、Viewのパーセントとマイナスの記号の違い

Railsを教えている時、Controllerの変数のアットマーク記号(@)とドルマーク($)の意味と、View(erb)のパーセント記号(%)とマイナス記号(-)の違いについて聞かれるので、その意味をまとめました。

バージョン

Ruby

Rails version: 6.1.4

Ruby on Rails

Ruby version: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux-musl]

Controllerのアットマーク記号(@)の意味と役割

アットマーク記号がない場合はローカル変数

宣言したブロックスコープの範囲でのみ利用可能です。別の場所で宣言した場合は、別の変数になります。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

  def sample

    puts "LocalVariable <<<"
    lv = 1
    puts lv
    local_variable
    puts lv
    puts "LocalVariable >>>"

  end

  private

  def local_variable
    puts "local_variable <<<"
    puts lv if defined? lv
    lv = 2
    puts lv
    puts "local_variable >>>"
  end

end

実行結果

Processing by ApplicationController#sample as HTML
LocalVariable <<<
1
local_variable <<<
2
local_variable >>>
1
LocalVariable >>>

アットマーク記号が1つ場合(@変数名)はインスタンス変数

インスタンス単位(newされたオブジェクト)で利用可能な変数です。インスタンスオブジェクト毎に異なる値が格納されます。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

  def sample

    puts "InstanceVariable <<<"
    iv1 = InstanceVariable.new(1)
    puts iv1.val
    iv2 = InstanceVariable.new(2)
    puts iv1.val
    puts iv2.val
    puts "InstanceVariable >>>"

  end

  private

  class InstanceVariable
    @val = nil

    def initialize(val)
      @val = val
    end

    def val
      @val
    end

  end

end

実行結果

Processing by ApplicationController#sample as HTML
InstanceVariable <<<
1
1
2
InstanceVariable >>>

アットマーク記号が2つ場合(@@変数名)はクラス変数

クラス単位で利用する変数です。インスタンスを複数用意しても、共通して利用する変数になります。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

  def sample

    puts "ClassVariable <<<"
    cv1 = ClassVariable.new(1)
    puts cv1.val
    cv2 = ClassVariable.new(2)
    puts cv1.val
    puts cv2.val
    puts "ClassVariable >>>"

  end

  private

  class ClassVariable
    @@val = nil

    def initialize(val)
      @@val = val
    end

    def val
      @@val
    end

  end
end

実行結果

Processing by ApplicationController#sample as HTML
ClassVariable <<<
1
2
2
ClassVariable >>>

Controllerのドルマーク記号($)の意味と役割

ドルマーク記号が1つの場合($変数名)はグローバル変数

プログラム全体で利用できる変数です。クラスや関数、スコープを越えて利用可能です。

app/controllers/application_controller.rb

$global = 99

class ApplicationController < ActionController::Base

  def sample

    puts "GlobalVariable >>>"
    puts $global
    global_variable(1)
    puts $global
    puts "GlobalVariable <<<"

  end

  private

  def global_variable(v)
    puts "global_variable <<<"
    puts $global if defined? $global
    $global = v
    puts $global
    puts "global_variable >>>"
  end

end

実行結果

GlobalVariable >>>
99
global_variable <<<
99
1
global_variable >>>
1
GlobalVariable <<<

View(erb)のパーセント記号(%)の意味と役割

ビュー(view) | Railsドキュメント

<% .. %>

プログラムを実行できます。変数宣言やループ処理で主に利用します。ブラウザには出力されません。

app/views/application/sample.rb

<h1>Sample</h1>

<% val = 1 %>
<% val %>
<% puts val %>
<% 1.upto(5) {|i| %>
upto
<% } %>

実行結果(ブラウザ)

Sample
upto upto upto upto upto

<%= .. %>

ブラウザに結果を出力することができます。

app/views/application/sample.rb

<h1>Sample</h1>

<% val = 99 %>
<%= val %>
<% 1.upto(5) {|i| %>
<%= i * i %>
<% } %>

実行結果(ブラウザ)

Sample
99 1 4 9 16 25

<%== .. %>

<%= .. %>はエスケープされて出力されますが、<%== .. %>はエスケープされずにそのままHTMLとして出力されます。クロスサイトスクリプティング(XSS)などの注意が必要です。

クロスサイトスクリプティング - Wikipedia

app/views/application/sample.rb

<h1>Sample</h1>

<%= "<strong>太字</strong>" %>
<%== "<strong>太字</strong>" %>

実行結果(ブラウザ)

Sample
<strong>太字</strong> 太字
&lt;strong&gt;太字&lt;/strong&gt;
<strong>太字</strong>

<%- .. %>、<% .. ->、<%- -%>

先頭のマイナスは空白を取り除き、末尾のマイナスは改行を取り除きます。イコールがない場合は、ブラウザに出力されません。

app/views/application/sample.rb

<h1>Sample</h1>

<% var = "B" %>

<h2><%%= %></h2>
<p>A
  <%= var %>
C</p>

<h2><%% -%></h2>
<p>A
  <% var -%>
C</p>

<h2><%%- -%></h2>
<p>A
  <%- var -%>
C</p>

<h2><%%= -%></h2>
<p>A
  <%= var -%>
C</p>

実行結果(ブラウザ)

Sample
<%= %>
A B C

<% -%>
A C

<%- -%>
A C

<%= -%>
A BC

<% =begin %>..<% =end %>

beginとendの間は出力されません。

app/views/application/sample.rb

出力されます
<%
=begin
%>
出力されません
<%
=end
%>
出力されます

実行結果(ブラウザ)

Sample
出力されます 出力されます

<%# .. %>

コメントになります。<!-- -->はHTMLとして出力されるため、出力したくない時に利用可能です。

app/views/application/sample.rb

<h1>Sample</h1>

<%# コメントになります %>
A<%# "B" %>C

実行結果(ブラウザ)

Sample

AC

以上、よく利用される記号の役割をまとめてみました。バージョンによって挙動が異なると思うため、影響が出にくい実装をしていきましょう。

読むべき本