rubyのクラス変数

2022.07.26

クラス変数

@@を使いクラス直下に定義する。継承先の子孫クラスでも呼び出せる。

class_variablesメソッドを見るとインスタンスが作られる前にクラス変数は定義されていると分かる。Hogeクラスがロードされた時。

# クラス変数

class Hoge
  @@one = 1
  
  def a
    p @@one
  end
end

class Hoge2 < Hoge
end

p Hoge.class_variables #=> [:@@one]
h = Hoge.new
h.a #=> 1
p Hoge2.class_variables #=> [:@@one]

aメソッドで定義したクラス変数@@twoはaメソッドが呼び出された後であれば呼び出せる。メソッド内でも定義できるが分かりにくそうな印象。

継承先でもクラス変数が確認できる。

class Hoge
  @@one = 1
  
  def a
    @@two = 2
    p @@one
  end

  def b
    p @@two
  end
end

class Hoge2 < Hoge
end

p Hoge.class_variables #=> [:@@one]
p Hoge2.class_variables #=> [:@@one]
h = Hoge.new
h.b #=> `b': uninitialized class variable @@two in Hoge (NameError)
h.a #=> 1
h.b #=> 2
p Hoge.class_variables #=> [:@@one, :@@two]
p Hoge2.class_variables #=> [:@@one, :@@two]

子クラスでクラス変数を書き換えると親クラスの値も変わる。子クラスで定義したクラス変数は親クラスでは呼び出すことはできない。

class Hoge
  @@one = 1
  
  def a
    @@two = 2
    p @@one
  end

  def b
    p @@two
  end
end

p Hoge.class_variable_get(:@@one) #=> 1
p Hoge2.class_variable_get(:@@one) #=> uninitialized constant Hoge2 (NameError)

class Hoge2 < Hoge
  @one = 10
  @three = 3
end

p Hoge.class_variable_get(:@@one) #=> 10
p Hoge2.class_variable_get(:@@one) #=> 10

p Hoge.class_variables #=> [:@@one, :@@two]
p Hoge2.class_variables #=> [:@@three, :@@one, :@@two]

h = Hoge.new
h.a #=> 10

まとめ

クラス変数は@@を使い定義する。子孫クラスでは継承できるが子孫クラスで定義したクラス変数を親クラスで使用することはできない。

子孫クラスでクラス変数の値を書き換えた場合は親クラスの値も書き変わる。