gold対策(模擬試験13)。
インスタンス間で共有され、かつ自分自身のクラスとサブクラスで管理される。
class A
@@x = 0
class << self
def x
@@x
end
end
def x
@@x = 2
end
end
class B < A
@@x = 3
end
p A.x
これだけでも気持ち悪いのですが、
もっと気持ち悪い例がメタプログラミングRuby(4.1.4)で紹介されています。
ちょっと変更して掲載すると
@@v = 1
class MyClass
@@v = 2
def v
@@v
end
end
@@v
MyClass.new.v
@@v = 3
MyClass.new.v
トップレベルで定義するとwarningが出ます。
こんな使い方はしないはずですが global変数のようです。
一応、global変数とは違う例を載せておきます。下記だとエラーとなります。
class MyClass
@@v = 2
end
@@v
こんな動きになるのは、
クラス変数がクラスに属していないからだ。
クラスではなく、クラス階層に属しているのだ。
@@vはmainのコンテキストで定義されているので、mainのクラスであるObjectに属していることになる。
それから、Objectのすべての子孫にも属しているかだ。
結局はみんなが同じクラス変数を共有しているというわけだ。
なるほど。試してみます。
class MyClass
@@v = 2
end
MyClass.class_variables
=> [:v]
>> Object.class_variables
=> []
@@v = 1
class MyClass; end
>> MyClass.class_variables
=> [:v]
>> Object.class_variables
=> [:v]
これは、恐ろしい。
多くのRubyistはクラス変数を使わずにクラスインスタンス変数を使っている。
使わないに越したことはないですね。