アットマーク(@)の意味は?【Ruby on Rails超入門】初心者にも分かりやすく解説

2019年1月2日水曜日

プログラミング

アットマーク Ruby on Rails

こんにちは、財前航介です。

Ruby on Railsで開発をしていると、アットマーク(@)が付いた変数を目にすることがありますね。

基本的にはこれは、Rubyで言うところのインスタンス変数と呼ばれるものの印です。
しかしこのインスタンス変数は、Ruby on Railsのコントローラーにおいては、少し特別な意味合いも持ちます。

場合によっては、クラス変数などとも呼ばれる、このアットマーク付きの変数。。。

ここは少し紛らわしい部分ですので、この記事では、アットマーク(@)付きの変数について、詳しく学んでいきましょう。


アットマーク(@)の意味は?【Ruby on Rails超入門】

アットマークの意味【Ruby on Rails超入門】

結論から言うと、この記事で理解して頂きたいのは、以下の3点です。

  • Rubyにおけるアットマーク(@)は、オブジェクトのインスタンス変数を表す

  • Ruby on Railsのコントローラークラスにおけるインスタンス変数は、ビューから参照できる

  • アットマークが2つ(@@)付いた変数は、クラス変数になる

一つずつ詳細を見ていきましょう。


Rubyにおけるアットマーク(@)は、オブジェクトのインスタンス変数を表す


Rubyにおいてアットマーク(@)が付いた変数はインスタンス変数と呼ばれるのですが、これを理解するには、オブジェクト指向についてある程度知っておく必要があります。

ご存知の方も多いと思いますが、Rubyはオブジェクト指向のプログラミング言語です。

オブジェクト指向とは、モノにたとえてプログラムの部品を作る考え方です。
オブジェクトとは、「データ」「処理」という2つの側面を持っているものです。

たとえば人間というものは、氏名年齢身長体重といったデータを持っています。

また、人間は「歩く」「走る」「しゃべる」といった、処理(動作)を行うことができますね。

こういう現実世界のモノになぞらえて、プログラムを記載していくのが、オブジェクト指向の考え方です。

オブジェクト指向の詳細を知りたい方は、以下の過去記事をご参照ください。
【初心者向け】オブジェクト指向とは >>

オブジェクト指向プログラミングの基本的な概念として、クラスインスタンスというものがあります。

ここではクラスとは、漠然としたモノだと思ってください。
たとえば、「人間」とか「犬」とか「車」とかですね。

それに対してインスタンスとは、「太郎君」とか「ポチ」とか「吉田さんのマイカー」とか、具体的に実体のあるモノだと考えると良いでしょう。

クラスとインスタンスの関係についてもっと知りたい方は、以下の過去記事を見て頂くと良いと思います。
【オブジェクト指向の基本】クラスとは >>
【オブジェクト指向の基本】インスタンスとは >>

Rubyプログラム内でアットマーク(@)が付いた変数を見たときは、ほとんどの場合、それはインスタンス変数であると考えて良いでしょう。

たとえば同じ人間でも、太郎君と花子さんは、名前が違いますね。

人間クラス太郎インスタンスと、花子インスタンスは、それぞれがインスタンス固有の「名前」という値を持っています。

ここでいう「名前」のように、同じクラスでも、インスタンス毎に違う値を持てるような変数を、インスタンス変数と呼びます。

言葉で説明しても分かりにくいので、具体的なソースコードの例を見てみましょう。

インスタンス変数の例

#Humanクラス
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」という変数を持っていますね。

これこそが、インスタンス変数です。

上記の例では、human1human2という2つのインスタンスを生成し、それぞれに「太郎」「花子」という値を与えています。

この「太郎」「花子」という値は、インスタンス変数@nameとして格納されるため、インスタンス固有の値となります。

最後の部分では、human1human2それぞれの名前を出力していますが、実行結果は以下のようになります。

実行結果

太郎
花子

それぞれのインスタンス固有の名前が出力されています。

このように、アットマーク(@)が付いた変数は、そのクラスのインスタンス変数となり、インスタンス固有の値を格納するために使われます。


Ruby on Railsのコントローラークラスにおけるインスタンス変数は、ビューから参照できる


上記の通り、Rubyプログラミングにおいてアットマーク(@)はインスタンス変数を表すものです。

しかし、Ruby on Railsというフレームワークを用いて開発を行う場合、このインスタンス変数が特別な意味を持つ場合があります。

どういう事かというと、
「コントローラークラスのインスタンス変数は、ビューからも参照できる」
という性質があるのです。

Ruby on Railsのコントローラービューの関係に関しては、以前、以下のような記事を書きました。
【Ruby on Rails超入門】コントローラーとビューの関係 >>


処理の流れの詳細は上記の記事に記載していますが、コントローラークラスのインスタンス変数として設定した値は、ビューから呼び出して、HTMLに埋め込むことができるのです。

上記の記事では、以下のような例を使ってご説明をしていますね。

アットマークがついた変数の例

これは、コントローラークラスの2つのインスタンス変数をビューに埋め込んでいる例です。
ビューには基本的にはHTMLが記載されているのですが、上記のようにコントローラー側でインスタンス変数を持っていると、その中身をHTML内に表示することができるのです。

上記の場合は、インスタンス変数1には「1つ目のインスタンス変数です。」という文字列が格納されており、
インスタンス変数2には、日付が格納されています。

ブラウザからURLを入力すると、コントローラークラスのインスタンス変数がHTML上に展開され、その結果がブラウザーに送信されるため、上記のような画面が表示されるのです。

詳細な処理の流れが知りたい方は、上記のコントローラーとビューの関係という記事をご参照下さい。

このように、Ruby on Railsのコントローラークラスに定義されたインスタンス変数は、単純に「インスタンス固有の値」というだけでなく、特別な意味合いを持ちます。

ここでは、
「インスタンス変数の値は、コントローラーとビューで共有される」
と、覚えておいてください。


アットマークが2つ(@@)付いた変数は、クラス変数になる


アットマーク(@)が付いた変数はインスタンス変数になるということは上記で説明しましたが、実は、アットマークが2つ付くと、その変数はクラス変数になるという決まりがあります。

クラス変数とは、そのクラスの全てのインスタンスで共有される変数です。
さらに言うと、インスタンスが一つも生成されていないクラスにおいても、使うことができる変数です。

言葉で説明すると分かりにくいので、先ほどの例を見てみましょう。

クラス変数の例

#Humanクラス
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において、クラス変数はスレッドセーフにならないという点です。

Webアプリケーションにおけるスレッドセーフとは、Webサーバーに複数人がアクセスしてきたときに、その間で値が共有されないことを意味しています。

たとえばAさんがECサイトで買い物をしているときに、少し後にBさんがそのECサイトにログインしたからと言って、Aさんが操作している画面に「こんにちはBさん」と表示されたら、おかしいですよね。

普通に考えたらそんなことは起こりえないような気がしますが、これは、通常のWebアプリケーションにおいては、スレッドセーフというものが保証されているからです。

しかし、Ruby on Railsでクラス変数を用いた場合、このスレッドセーフは保証されません。

AさんBさんの間で、クラス変数の値が共有されてしまうのです。

PHPなどではこのようなことは起こらないのですが、Ruby on Railsを用いる際は、気を付けなければいけない点です。


Ruby on Railsには多くのメリットがある反面、このようなデメリットもあります。

Ruby on Railsを用いる上でのメリットデメリットについて知りたい方は、以下に詳しくまとめましたので、よろしければご覧ください。

Ruby on Railsのメリット・デメリット【初心者にもわかりやすく解説】 >>