simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

Rubyでのクラス変数、インスタンス変数、クラスインスタンス変数の違いについて

Rubyでは色々な変数が定義できます。そこでごっちゃになりやすそうな「クラス変数」と「インスタンス変数」と「クラスインスタンス変数」について自分なりにまとめてみました。

クラス変数

class Siman
  @@name = "siman"

  def print_siman
    puts @@name
  end
end

class Simanman < Siman
  def print_simanman
    puts @@name
  end
end

s1 = Siman.new
s2 = Simanman.new

s1.print_siman
s2.print_simanman
siman
siman

クラス変数は「@@」から始まる変数のことを指します。クラス変数は継承されたクラスにも反映されるので、SimanクラスのサブクラスであるSimanmanクラスも、@@nameを参照できていることが実行結果からわかります。

ちなみに

rubyではよくアクセサメソッドとして「attr_accessor」「attr_reader」「attr_writer」などがありますが、クラス変数には適用できないので、クラス変数のアクセサを使用したい場合は自分で定義する必要があります。

class Siman
  @@name = "siman"

  def print_siman
    puts @@name
  end

  def name
    @@name
  end

  def name=(val)
    @@name = val
  end
end

s1 = Siman.new

s1.print_siman

s1.name = "simanman"
s1.print_siman
siman
simanman

これでクラス変数にも参照&代入ができるようになりました。



インスタンス変数

インスタンス変数はクラスのインスタンスで使用出来る変数である。以上

class Siman
  attr_accessor :name

  def initialize
    @name = "siman"
  end
end

s = Siman.new
puts s.name
siman


また、インスタンス変数はインスタンスごとに違う値を保持することができる。

class Siman
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

s1 = Siman.new("siman")
s2 = Siman.new("simanman")

puts s1.name
puts s2.name
siman
simanman


あと、インスタンス変数は値が代入された時に初めて生成されるので、注意が必要。

class Siman
  attr_accessor :name

  def name_define
    @name = "siman"
  end
end

s1 = Siman.new()

p s1.instance_variables
s1.name_define
p s1.instance_variables
[]
[:@name]


クラスインスタンス変数

クラスインスタンス変数は「クラス内で参照できる変数」です。なので、クラス変数とは違ってサブクラスから親のクラスインスタンス変数は参照できません。

class Siman
  @name = "siman"

  def self.print_siman
    puts "my name is #{@name}"
  end
end

class Simanman < Siman
  def self.print_simanman
    puts "my name is #{@name}"
  end
end

Siman.print_siman
Simanman.print_simanman
my name is siman
my name is 

実行結果をみるとわかる通りprint_simanmanでは何も出力されていないことがわかる。


クラスインスタンス変数はインスタンス変数とごっちゃになりやすいので注意が必要。変数の定義場所をハッキリさせよう!


・クラスインスタンス変数とインスタンス変数の定義範囲


f:id:simanman:20130311205824j:plain


これらの変数の違いを把握することでRubyのプログラミングの幅が広がります。



参考ページ

Ruby クラス変数のゲッタ」
http://tac-rightning.jugem.jp/?eid=643
「クラス変数とクラスインスタンス変数とインスタンス変数の違いについて」
http://d.hatena.ne.jp/kabakiyo/20080525/1211728832