0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Ruby初学者】クラス変数(@@var)の挙動について

Posted at

Rubyのクラス変数(@@var)の挙動を学ぶ

Rubysilvar取得に向けて学習をしているのですが、クラス変数の挙動でつまづいたので

  • @@var がどこまで共有されるのか?
  • Foo と Bar(継承関係)で値はどう変化する?
  • 出力結果はどうなる?

という点をまとめます。


問題のコード

class Foo
  @@var = 0

  def var
    @@var
  end

  def var=(value)
    @@var = value
  end
end

class Bar < Foo
end

foo = Foo.new
foo.var += 1
bar = Bar.new
bar.var += 2

puts "#{foo.var}/#{bar.var}"

上記は3/3


Rubyのクラス変数(@@var)はクラス階層で1つだけ共有

Rubyの@@varは、**そのクラスとサブクラス全体で"1つだけ"共有される。

  • Foo のインスタンス
  • Bar(Foo のサブクラス)のインスタンス
    すべてが同じ@@varを参照

処理の流れ

①最初の状態

@@var = 0

②fooの処理

foo = Foo.new
foo.var += 1

内部的にはこう動く

  1. foo.var@@varを読み出す(0)
  2. @@var = 0 + 1

結果

@@var = 1

③barの処理

BarはFooを継承している。同じクラス変数を共有する。

bar = Bar.new
bar.var += 2

内部的には

  1. bar.var → 現在の @@var(1)
  2. @@var = 1 + 2

結果

@@var = 3

④出力

puts "#{foo.var}/#{bar.var}"

どちらも同じ@@varを読みにいく

3/3

となる。


なぜ1/2ではないのか?

直感的に「Fooは1、Barは2」になると思ったけども、クラス変数はインスタンスごとではなく"クラス階層全体で1つのため、

  • Fooが変更 → Barでも変更済みの値が見える
  • Barが変更 → Fooからも同じ値が見える
    という挙動になる。

まとめ

  • @@varはクラス階層全体で共有される
  • FooもBarも同じ1つの変数を見ている
  • よって出力は 3/3

初学者のため、間違えていたらすいません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?