【Ruby入門】変数の種類まとめ【インスタンス変数、クラス変数、グローバル変数】

Ruby の変数にはいくつか種類があり、用途に応じて使い分ける必要があります。

以下から Ruby の変数の種類を解説していきます。

メモ

そもそも変数とは何か? という話はこちら

 

Ruby で使える変数の種類

Ruby の変数には以下の種類があります。

  • ローカル変数
  • インスタンス変数
  • クラス変数
  • クラスインスタンス変数
  • グローバル変数
  • 定数

 

変数ごとに、スコープ(プログラム中でその変数が参照できる範囲)に違いがあります。

例えば、クラス内だけで使えるものや、さらに狭い範囲のメソッド内だけで使えるものがあるといった具合です。

もしすべての変数がプログラム全体で使えるようになっていたら、変数名が被ってしまうと 関係のないコードにまで影響を与えてしまいます。プログラムを書くときに常に影響範囲を考慮しながら変数名に気を配るのは大変なので、必要な範囲だけ変数が参照できるようにスコープという概念があります。

 

以下からは、それぞれの変数ごとに使い方を解説していきます。

 

ローカル変数

特徴

  • 変数名には英数字やアンダーバー(_)が使える。
  • 先頭の文字を数字にできない。
  • メソッドやクラス、モジュールの中で定義された範囲内でのみ参照できる。定義された場所以外からは参照できない。

 

プログラム例 その1

以下はローカル変数を使って計算を行う例。

プログラム
score1 = 2
score2 = 3

p score1 + score2
実行結果
5

score1score2 という名前の変数に数値を代入して、それを足し合わせた結果を表示しています。

 

プログラム例 その2

以下のようにメソッドをまたがって変数を使用することはできません。この例ではエラーとなります。

プログラム
class User
  def login(user_name)
    name = user_name
  end

  def display_current_user
    p name
  end
end

user = User.new
user.login("山田")
user.display_current_user

user.login("山田") で login メソッドを呼び出し、その中で「name」という名前の変数に引数の「山田」を代入しています。

次に user.display_current_user で display_current_user メソッドを呼び出し、その中で「name」という名前の変数の値を表示していますが、login メソッドの中の「name」変数は参照できないため、エラーとなります。

 

インスタンス変数

特徴

  • 変数名の先頭に @ をつける。
  • クラスから生成されるインスタンスの範囲内で参照できる。同じクラスから生成されたインスタンスであっても、別のインスタンスの変数は参照できない。

 

プログラム例 その1

以下はインスタンス変数を用いた例。

プログラム
class User
  def login(user_name)
    @name = user_name
  end

  def display_current_user
    p @name
  end
end

user = User.new
user.login("山田")
user.display_current_user
実行結果
"山田"

user.login("山田") で login メソッドを呼び出し、その中で「@name」という変数に引数の「山田」を代入しています。

次に user.display_current_user で display_current_user メソッドを呼び出し、その中で「@name」という変数の値を表示しています。他のメソッドで宣言した「@name」であっても参照できるので、変数の値である「山田」が表示されます。

 

プログラム例 その2

以下のように複数のインスタンスを生成した場合は、インスタンスごとに変数の値が保持されます。

プログラム
class User
  def login(user_name)
    @name = user_name
  end

  def display_current_user
    p @name
  end
end

user1 = User.new
user1.login("山田")
user1.display_current_user

user2 = User.new
user2.login("田中")
user2.display_current_user
実行結果
"山田"
"田中"

User.new を使って「user1」と「user2」という名前の変数に「User」クラスから生成したインスタンスを代入しています。

user1.display_current_useruser2.display_current_user で「@name」の値を表示していますが、同じ変数名であってもインスタンスごとに値が保持されているので、違う値が表示されることが確認できます。

 

クラス変数

特徴

  • 変数名の先頭に @@ をつける。
  • クラスと そこから生成されるインスタンスの範囲内で参照できる。別のインスタンスであっても同じクラスから生成されたものであれば、変数が共有できる。
  • 継承したクラスでも変数を参照できる。

 

プログラム例

以下はクラス変数を用いた例。

プログラム
class User
  def login(user_name)
    @@name = user_name
  end

  def display_current_user
    p @@name
  end
end

user1 = User.new
user2 = User.new
user1.login("山田")

user1.display_current_user
user2.display_current_user
実行結果
"田中"
"田中"

User.new を使って「user1」と「user2」という名前の変数に「User」クラスから生成したインスタンスを代入しています。

次に user1.login("山田") で login メソッドを呼び出し、その中で「@@name」という変数に引数の「山田」を代入しています。

「@@name」は同じクラスから生成されたインスタンスで共有されるので、 user1.display_current_user だけでなく、user2.display_current_user でも「@@name」の値が表示されることが確認できます。

 

クラスインスタンス変数

特徴

  • 変数名の先頭に @ をつける(インスタンス変数と同じだが、定義する場所が違う)。
  • クラス定義式内で定義する。
  • クラスメソッドから参照できる。インスタンスメソッドからは参照できない。
メモ

クラスメソッドやインスタンスメソッドについて詳しくはこちら(作成中)。

 

プログラム例 その1

以下はクラスインスタンス変数を用いた例。

プログラム
class User
  @name = "鈴木"

  def self.display_current_user
    p @name
  end
end

User.display_current_user
実行結果
"鈴木"

あらかじめクラスの中では「@name」というクラスインスタンス変数が定義されています。

User.display_current_user で、display_current_user というクラスメソッドから変数の値が参照できることが確認できます。

 

プログラム例 その2

以下のように、インスタンスメソッドからは クラスインスタンス変数は参照できません。

プログラム
class User
@name = "鈴木"

  def display_current_user
    p @name
  end
end

a = User.new
a.display_current_user
実行結果
nil

 

グローバル変数

特徴

  • 変数名の先頭に $ をつける。
  • プログラム内のどこからでも宣言・参照ができる。
  • 全体のプログラムに影響を与える可能性があるため、変数名が重複しないかチェックしたり、変数の値を変更して思わぬ場所でバグを生んだりしないように注意が必要。

 

プログラム例

以下はグローバル変数を用いた例。

プログラム
class User
  $name = "佐藤"

  def display_current_user
    p $name
  end

  def self.display_current_user
    p $name
  end
end

p $name

user = User.new
user.display_current_user

User.display_current_user
実行結果
"佐藤"
"佐藤"
"佐藤"

$name = "佐藤" で変数を定義していますが、メソッドやクラスの垣根なく、どこからでも参照できることが確認できます。

 

定数

特徴

  • 定数名の先頭は大文字にする(慣習として全て大文字にすることが多い)。
  • メソッドの中では定義できない。
  • クラス定義式内で定義しておくと、クラスメソッドやインスタンスメソッド、継承したクラスから参照できる。
  • 慣習として、宣言した定数の値をあとから変更することは あまりない(変更はできるけど警告が出る)。
メモ

クラスメソッドやインスタンスメソッドについて詳しくはこちら(作成中)。

 

プログラム例

以下は価格から消費税を計算するプログラム例。

プログラム
class Item
  TAX_RATE = 0.08

  def self.display_tax_price(price)
    p price * TAX_RATE
  end
end

Item.display_tax_price(100)

User.display_current_user
実行結果
8.0

TAX_RATE = 0.08 で、消費税を定数で宣言しておき、クラス内の計算で使います。

このようにプログラム内で共通で使う値を定数にしておくことで、コードを見るだけで何の数値かわかるようになります。また、消費税率が変わった場合は、定数の値を変えるだけでコード全体に反映することができるようになります。

 

定数の値は、以下のように クラス名::定数名 という形で外から参照することも可能です。

プログラム
class Item
  TAX_RATE = 0.08
end

p Item::TAX_RATE
実行結果
0.08

 

まとめ

以上、Ruby の変数の種類でした!

 

ここまでの内容をまとめておきます。

  • 変数ごとに、スコープ(プログラム中でその変数が参照できる範囲)に違いがある。
  • ローカル変数は、メソッドやクラス、モジュールの中で定義された範囲内でのみ参照できる。
  • インスタンス変数は、変数名の先頭に @ をつけ、クラスから生成されるインスタンスの範囲内で参照できる。
  • クラス変数は、変数名の先頭に @@ をつけ、クラスと そこから生成されるインスタンスの範囲内で参照できる。継承したクラスでも参照できる。
  • クラスインスタンス変数は、変数名の先頭に @ をつけ、クラス定義式内で定義することで、クラスメソッドから参照できる。
  • グローバル変数は、変数名の先頭に $ をつけ、プログラム内のどこからでも宣言・参照ができる。
  • 定数は、先頭は大文字(慣習として全て大文字にすることが多い)にして、クラス定義式内で定義しておくと、クラスメソッドやインスタンスメソッド、継承したクラスから参照できる。