こんにちは、財前航介です。
しかしこのインスタンス変数は、Ruby on Railsのコントローラーにおいては、少し特別な意味合いも持ちます。
場合によっては、クラス変数などとも呼ばれる、このアットマーク付きの変数。。。
アットマーク(@)の意味は?【Ruby on Rails超入門】

結論から言うと、この記事で理解して頂きたいのは、以下の3点です。
- Rubyにおけるアットマーク(@)は、オブジェクトのインスタンス変数を表す
- Ruby on Railsのコントローラークラスにおけるインスタンス変数は、ビューから参照できる
- アットマークが2つ(@@)付いた変数は、クラス変数になる
一つずつ詳細を見ていきましょう。
Rubyにおけるアットマーク(@)は、オブジェクトのインスタンス変数を表す
Rubyにおいてアットマーク(@)が付いた変数はインスタンス変数と呼ばれるのですが、これを理解するには、オブジェクト指向についてある程度知っておく必要があります。
ご存知の方も多いと思いますが、Rubyはオブジェクト指向のプログラミング言語です。
オブジェクトとは、「データ」と「処理」という2つの側面を持っているものです。
たとえば人間というものは、氏名や年齢、身長、体重といったデータを持っています。
また、人間は「歩く」、「走る」、「しゃべる」といった、処理(動作)を行うことができますね。
こういう現実世界のモノになぞらえて、プログラムを記載していくのが、オブジェクト指向の考え方です。
オブジェクト指向の詳細を知りたい方は、以下の過去記事をご参照ください。
【初心者向け】オブジェクト指向とは >>
ここではクラスとは、漠然としたモノだと思ってください。
たとえば、「人間」とか「犬」とか「車」とかですね。
それに対してインスタンスとは、「太郎君」とか「ポチ」とか「吉田さんのマイカー」とか、具体的に実体のあるモノだと考えると良いでしょう。
クラスとインスタンスの関係についてもっと知りたい方は、以下の過去記事を見て頂くと良いと思います。
【オブジェクト指向の基本】クラスとは >>
【オブジェクト指向の基本】インスタンスとは >>
Rubyプログラム内でアットマーク(@)が付いた変数を見たときは、ほとんどの場合、それはインスタンス変数であると考えて良いでしょう。
たとえば同じ人間でも、太郎君と花子さんは、名前が違いますね。
人間クラスの太郎インスタンスと、花子インスタンスは、それぞれがインスタンス固有の「名前」という値を持っています。
ここでいう「名前」のように、同じクラスでも、インスタンス毎に違う値を持てるような変数を、インスタンス変数と呼びます。
言葉で説明しても分かりにくいので、具体的なソースコードの例を見てみましょう。
インスタンス変数の例
class Human
#HumanクラスのsetNameメソッド
#(インスタンス変数に名前をセットする)
def setName(strName)
@name = strName
end
#HumanクラスのsayNameメソッド
#(インスタンスの@nameを出力する)
def sayName()
print(@name, “¥n”)
end
end
#上記のHumanクラスのインスタンスを生成
human1 = Human.new()
#human1に「太郎」という名前を付ける
human1.setName(“太郎”)
#Humanクラスのインスタンスをもう一つ生成
human2 = Human.new()
#human2に「花子」という名前を付ける
human2.setName(“花子”)
#human1の名前を出力
human1.sayName()
#human2の名前を出力
human2.sayName()
上記のHumanクラスは「@name」という変数を持っていますね。
これこそが、インスタンス変数です。
上記の例では、human1とhuman2という2つのインスタンスを生成し、それぞれに「太郎」と「花子」という値を与えています。
この「太郎」と「花子」という値は、インスタンス変数@nameとして格納されるため、インスタンス固有の値となります。
最後の部分では、human1とhuman2それぞれの名前を出力していますが、実行結果は以下のようになります。
実行結果
花子
それぞれのインスタンス固有の名前が出力されています。
このように、アットマーク(@)が付いた変数は、そのクラスのインスタンス変数となり、インスタンス固有の値を格納するために使われます。
Ruby on Railsのコントローラークラスにおけるインスタンス変数は、ビューから参照できる
上記の通り、Rubyプログラミングにおいてアットマーク(@)はインスタンス変数を表すものです。
しかし、Ruby on Railsというフレームワークを用いて開発を行う場合、このインスタンス変数が特別な意味を持つ場合があります。
どういう事かというと、
「コントローラークラスのインスタンス変数は、ビューからも参照できる」
という性質があるのです。
Ruby on Railsのコントローラーとビューの関係に関しては、以前、以下のような記事を書きました。
【Ruby on Rails超入門】コントローラーとビューの関係 >>
処理の流れの詳細は上記の記事に記載していますが、コントローラークラスのインスタンス変数として設定した値は、ビューから呼び出して、HTMLに埋め込むことができるのです。
上記の記事では、以下のような例を使ってご説明をしていますね。

ビューには基本的にはHTMLが記載されているのですが、上記のようにコントローラー側でインスタンス変数を持っていると、その中身をHTML内に表示することができるのです。
上記の場合は、インスタンス変数1には「1つ目のインスタンス変数です。」という文字列が格納されており、
インスタンス変数2には、日付が格納されています。
ブラウザからURLを入力すると、コントローラークラスのインスタンス変数がHTML上に展開され、その結果がブラウザーに送信されるため、上記のような画面が表示されるのです。
詳細な処理の流れが知りたい方は、上記の「コントローラーとビューの関係」という記事をご参照下さい。
このように、Ruby on Railsのコントローラークラスに定義されたインスタンス変数は、単純に「インスタンス固有の値」というだけでなく、特別な意味合いを持ちます。
ここでは、
「インスタンス変数の値は、コントローラーとビューで共有される」
と、覚えておいてください。
アットマークが2つ(@@)付いた変数は、クラス変数になる
アットマーク(@)が付いた変数はインスタンス変数になるということは上記で説明しましたが、実は、アットマークが2つ付くと、その変数はクラス変数になるという決まりがあります。
クラス変数とは、そのクラスの全てのインスタンスで共有される変数です。
さらに言うと、インスタンスが一つも生成されていないクラスにおいても、使うことができる変数です。
言葉で説明すると分かりにくいので、先ほどの例を見てみましょう。
クラス変数の例
class Human
#HumanクラスのsetNameメソッド
#(インスタンス変数に名前をセットする)
def setName(strName)
@@name = strName
end
#HumanクラスのsayNameメソッド
#(@@nameを出力する)
def sayName()
print(@@name, “¥n”)
end
end
#上記のHumanクラスのインスタンスを生成
human1 = Human.new()
#human1に「太郎」という名前を付ける
human1.setName(“太郎”)
#Humanクラスのインスタンスをもう一つ生成
human2 = Human.new()
#human2に「花子」という名前を付ける
human2.setName(“花子”)
#human1の名前を出力
human1.sayName()
#human2の名前を出力
human2.sayName()
この例は、先ほどのインスタンス変数の例で見たプログラムを、ほんの少しだけ修正したものです。
具体的には、先ほどまでインスタンス変数だった@nameを、@@nameとして、クラス変数にしました。
これによって、実行結果は以下のように変わります。
実行結果
花子
先ほどまでは「太郎, 花子」だった実行結果が、「花子, 花子」になっています。
これはなぜかというと、クラス変数は、そのクラスの全てのインスタンスで共有される値だからです。
つまり、human2の@@nameに「花子」という値を代入したとき、「太郎」という値を上書きしてしまっているのですね。
そのため、human1から見たときも、human2から見たときも、@@nameの値は「花子」になってしまったのです。
このように、アットマーク(@)が2つ付いている変数は、クラス変数となり、そのクラスの全てのインスタンスで値が共有されます。
Ruby on Railsにおけるクラス変数の注意点: スレッドセーフにならない!

上記で説明したように、クラス変数とは、アットマーク(@)が2つ付いている変数のことですが、Ruby on Railsでクラス変数を用いる際に注意しなければいけない点があります。
それは、Ruby on Railsにおいて、クラス変数はスレッドセーフにならないという点です。
たとえばAさんがECサイトで買い物をしているときに、少し後にBさんがそのECサイトにログインしたからと言って、Aさんが操作している画面に「こんにちはBさん」と表示されたら、おかしいですよね。
普通に考えたらそんなことは起こりえないような気がしますが、これは、通常のWebアプリケーションにおいては、スレッドセーフというものが保証されているからです。
しかし、Ruby on Railsでクラス変数を用いた場合、このスレッドセーフは保証されません。
AさんとBさんの間で、クラス変数の値が共有されてしまうのです。
PHPなどではこのようなことは起こらないのですが、Ruby on Railsを用いる際は、気を付けなければいけない点です。
Ruby on Railsには多くのメリットがある反面、このようなデメリットもあります。
Ruby on Railsを用いる上でのメリットやデメリットについて知りたい方は、以下に詳しくまとめましたので、よろしければご覧ください。
コメント