今回はクラス変数とインスタンス変数の違いについてまとめてみました。
クラスとインスタンス、クラスメソッドとインスタンスメソッドなど似たような用語がたくさん出てきていますが、1つ1つ順番に理解していきましょう。
例題
以下のようなコードを設定しました。
具体的には、Reviewクラスにインスタンスメソッド(write_reviewとshow_review)を2つ定義しています。
class Review
def write_review
puts "タイトルを入力してください"
title = gets.chomp
puts "ジャンルを入力してください"
genre = gets.chomp
puts "感想を入力してください"
impression = gets.chomp
end
def show_review
line = "----------------"
puts "ジャンル : #{genre}\n#{line}\n"
puts "タイトル : #{title}\n#{line}\n"
puts "感想 :\n#{impression}\n#{line}\n"
end
end
では次に、このインスタンスメソッドを呼び出す記述を追記しましょう。
class Review
def write_review
puts "タイトルを入力してください"
title = gets.chomp
puts "ジャンルを入力してください"
genre = gets.chomp
puts "感想を入力してください"
impression = gets.chomp
end
def show_review
line = "----------------"
puts "ジャンル : #{genre}\n#{line}\n"
puts "タイトル : #{title}\n#{line}\n"
puts "感想 :\n#{impression}\n#{line}\n"
end
end
Review.new # インスタンスの生成
review.write_review # write_reviewの呼び出し
review.show_review # show_reviewの呼び出し
するとどうでしょうか。

タイトル・ジャンル・感想は入力できるものの、それらの情報が表示されていませんね。
言い換えると、write_reviewメソッドの呼び出しは成功していますが、show_reviewの呼び出しに失敗していると言えます。
その原因は何でしょうか?
答えはスコープです。
スコープとは、メソッドの中で定義した変数はメソッドの中でしか使えず、メソッドの外で定義した変数はメソッドの中では使えないというものです。
スコープについてはこちらの記事でも解説しています。
https://techtechmedia.com/argument-ruby/
この問題を解決してくれるのがインスタンス変数です。
インスタンス変数
インスタンス変数とは、クラスの中のどのインスタンスメソッドでも使用可能にするものです。
言い換えると、インスタンス変数のスコープは、そのクラスの全てのインスタンスメソッドです。
定義方法
クラス内のメソッドの中で、変数名の始めに@(アットマークを1つ)をつけて定義します。
class クラス名
def メソッド名
@変数名 = 値 # インスタンス変数
end
end
使用例
先ほどの例題で見ていきましょう。
class Review
def write_review
puts "タイトルを入力してください"
title = gets.chomp
puts "ジャンルを入力してください"
genre = gets.chomp
puts "感想を入力してください"
impression = gets.chomp
end
def show_review
line = "----------------"
puts "ジャンル : #{genre}\n#{line}\n"
puts "タイトル : #{title}\n#{line}\n"
puts "感想 :\n#{impression}\n#{line}\n"
end
end
Review.new # インスタンスの生成
review.write_review # write_reviewの呼び出し
review.show_review # show_reviewの呼び出し
このままだと、インスタンスメソッド(write_review)で入力された情報はスコープの範囲外のため、別のインスタンスメソッド(show_review)に渡すことができません。
そこで、以下のようにインスタンス変数を定義しましょう。
class Review
def write_review
puts "タイトルを入力してください"
@title = gets.chomp
puts "ジャンルを入力してください"
@genre = gets.chomp
puts "感想を入力してください"
@impression = gets.chomp
end
def show_review
line = "----------------"
puts "ジャンル : #{@genre}\n#{line}\n"
puts "タイトル : #{@title}\n#{line}\n"
puts "感想 :\n#{@impression}\n#{line}\n"
end
end
Review.new # インスタンスの生成
review.write_review # write_reviewの呼び出し
review.show_review # show_reviewの呼び出し
こうすることで、2つのインスタンスメソッド(write_reviewとshow_review)の結果が出力されましたね。
クラス変数
クラス変数とは、クラス全体で使用できる変数です。
クラス内であればどこでも使えるので、クラスメソッド・インスタンスメソッドの両方でも使うことができます。
定義方法
クラス変数は、変数名の始めに@@(アットマークを2つ)をつけて定義します。
class クラス名
@@変数名 = 値
end
使用例
それでは、例を見ていきましょう。
今回はレビュー数を返す「get_review_countメソッド」を定義します。
class Review
@@review_count = 0
def self.get_review_count
return @@review_count
end
def write_review
puts "タイトルを入力してください"
@title = gets.chomp
puts "ジャンルを入力してください"
@genre = gets.chomp
puts "感想を入力してください"
@impression = gets.chomp
@@review_count = @@review_count + 1
end
def show_review
line = "---------------------------"
puts "ジャンル : #{@genre}\n#{line}\n"
puts "タイトル : #{@title}\n#{line}\n"
puts "感想 :\n#{@impression}\n#{line}\n"
end
end
review = Review.new # Reviewクラスのインスタンスを生成
review.write_review # write_reviewメソッドを実行
review.show_review # show_reviewメソッドを実行
puts Review.get_review_count
このように記述することによって、レビューを追加すると、最終行(puts Review.get_review_count)でレビュー数が表示されるようになります。
今回の記述では、レビュー数は0から1にしか変わりません。
今回はクラス変数とインスタンス変数の違いについてまとめました。
この違いを理解するには、スコープという概念がしっかり頭に入っていないと難しいので、ピンと来ていない場合はスコープから学習し直しましょう!