るりまと(旧)Rubyリファレンスマニュアルでクラス変数の説明が違う
題意通り
ちょっと、クラス変数を持つクラスを継承したときの動作を勘違いしておりました。
class Hoge @@hoge = 0 def self.hoge @@hoge end end class Moge < Hoge def hoge=(i) @@hoge = i end end class Fuga < Hoge def hoge=(i) @@hoge = i end end
という感じのときに、MogeとFugaのクラス変数hogeは独立されるのかなぁと思っていたら、違うんですね。もうちょっと、ちゃんとオブジェクト指向勉強しないといけませんね。
どうやら、継承されたクラスで独立したクラス変数を扱いたい時は、クラスインスタンス変数というのを使うのがよいらしい。Martin Fowler's Bliki in Japanese - クラスインスタンス変数
で、クラス変数について調べていたんだけど、旧Rubyリファレンスマニュアル変数と定数見てみたらこう書いてある
クラス変数はクラス自身のインスタンス変数とは以下の点で異なります。 * サブクラスから参照/代入が可能 (1.8まで*1) * インスタンスメソッドから参照/代入が可能 *1 1.9では不可能 http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l39
いっぽう、るりまの1.9.1の変数と定数には、こうかいてある。
クラス変数はクラス自身のインスタンス変数とは以下の点で異なります。 * サブクラスから参照/代入が可能 * インスタンスメソッドから参照/代入が可能
で、1.9の環境でやってみたんだけど、サブクラスから参照代入可能だった。
takkanm% cat hoge.rb #! /opt/local/bin/ruby1.9 class Hoge @@hoge = 0 def self.hoge p @@hoge end end class Moge < Hoge def hoge=(i) @@hoge = i end end class Fuga < Hoge def hoge=(i) @@hoge = i end end m = Moge.new f = Fuga.new [Hoge, Moge, Fuga].map(&:hoge) m.hoge = 100 [Hoge, Moge, Fuga].map(&:hoge) f.hoge = 10 [Hoge, Moge, Fuga].map(&:hoge) takkanm% ruby1.9 hoge.rb 0 0 0 100 100 100 10 10 10
というわけで、マニュアルはるりまを使ったほうがいいみたいですね。