クラス変数がよくわからん
rubyで、クラスをコピーしたときのクラス変数の挙動が謎だ。
順番に説明する。まずは以下のクラス変数@@iを定義するたわいもないクラス定義を見て欲しい。
class Base def i @@i end def i=(a) @@i = a end end
こうするとBaseのインスタンスは全てクラス変数@@iを共有する。例えばこんなかんじ。
a = Base.new a.i = 100 b = Base.new #bはaとは違うインスタンスだけど p b.i #=> 100 #クラス変数@@iを共有しているので、100が得られる
でもって、rubyでは継承関係にあるクラス間でクラス変数も共有される。
class Child < Base end a = Base.new a.i = 100 b = Child.new #継承したクラスChildのインスタンスでも… p b.i #=> 100 #クラス変数を共有している
ここまではいい。問題はBaseをdupすると、というケース。実はdupしたクラスもクラス変数を共有してしまう。
Copy = Base.dup a = Base.new a.i = 100 b = Copy.new #コピーしたクラスのオブジェクトでも… p b.i #=> 100 #クラス変数を共有している
あちゃー、そこまで共有するのかーまあそういうもんかー。と、一瞬思ったが、どうにもふに落ちなかったので、class_variablesも表示させてみた。本来、class_variablesはクラス変数一覧を配列で返してくれるはずなのだが…
Base.new.i = 100 p Base.class_variables p Copy.class_variables #=> ["@@i"] []
なんとCopyのほうが空だ。
ここまで来るとさすがに、class_variablesか、あるいはクラスをdupしたときのクラス変数の挙動のどちらかがおかしいように思える。なんだろうこれ。
もしかしてバグですか?