👽

Rubyのクラスインスタンス変数とは何か

2023/04/02に公開

クラスインスタンス変数

クラスインスタンス変数とは、クラス内で@hogeなどと@をつけて定義する変数を指す。たとえば、以下のようなクラスがあるとする。

class Parent
  @name = "John" #クラスインスタンス変数を定義

  def self.name
    @name #クラスインスタンス変数を返す
  end
end

Parentクラスでは、クラスインスタンス変数を定義している。さらに、クラスインスタンス変数を返すクラスメソッドParent.nameを定義している。

# クラスインスタンス変数が返る
p Parent.name #=> "John"

インスタンス変数を定義・参照しているような雰囲気を醸し出しているが、これはクラスインスタンス変数だ。試しにインスタンス変数を定義してみるとどうなるだろう?

class Parent
  @name = "John"

  def self.name
    @name
  end

  # インスタンス変数を定義する
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

p Parent.name #=> "John"
p Parent.new("James").name #=> "James"

同じ変数名を2つ定義していてわかりにくいが、それぞれクラスインスタンス変数とインスタンス変数を返している。

次に、Parentクラスを継承したChildクラスを作成する。

class Parent
  @name = "John"

  def self.name
    @name
  end
end

class Child < Parent
  #Childクラス内には何も定義しない
end

この状態で、@nameを参照してみるとどうなるか?

p Parent.name #=> "John"
p Child.name #=> nil

Childクラスから@nameを参照してもnilが返る。つまり、継承先のサブクラスからはクラスインスタンス変数を参照できず、エラーにはならないがnilが返る。

では、Childクラス内にも同名のクラスインスタンス変数を定義してみよう。

class Parent
  @name = "John"

  def self.name
    @name
  end
end

class Child < Parent
  # サブクラス内でクラスインスタンス変数を定義する
  @name = "Ken" 
end

すると、このような結果になる。

p Parent.name #=> "John"
p Child.name #=> "Ken"

それぞれのクラスで定義された変数の値を返している。

Rubyのクラスインスタンス変数とは

  • クラス内で@で始めて定義するクラス自身の変数である
  • スーパークラスで定義したクラスインスタンス変数を、そのサブクラスから参照してもnilが返る

Discussion