クラス変数の注意点

クラス変数なんて、めったに使うことなんてないし、railsで使うならclass_attributeがあるんで、普通は必要ないです。

しかし、よくクラス変数やめろ!なんて言われることが多いと思うので、ここでおさらいしておきます。

クラス変数とは

そもそもクラス変数ってなんぞや?

クラス間で共有出来る変数ですね。

例えば、下記のようなものです。

class Foo
  @@x = 1

  def x
    @@x
  end

  def x=value
    @@x = value
  end
end

pry(main)> a = Foo.new
=> #<Foo:0x007f89982500e8>
pry(main)> a.x = 3
=> 3
pry(main)> b = Foo.new
=> #<Foo:0x007f8998343978>
pry(main)> b.x = 5
=> 5
pry(main)> a.x
=> 5

確かに共有されますね。

ただし、厄介なことがあります。

  • サブクラスにも継承される
  • クラス階層に属している

前者はわかりやすいと思うので、後者について説明します。

先程の続きです。

pry(main)> @@x = 6
(pry):17: warning: class variable access from toplevel
=> 6
pry(main)> b.x
=> 6

上記のように、mainクラスの時に変更したものも値が変更されてしまいます。

こういう罠が多いので、クラス変数は使うなってことになります。

けど、どうしてもクラス間で共有したいって時があります。

そういう場合はどうすればいいのかってことです。

あくまでもrails側の方法です。

class_attribute

railsではclass_attributeがあります。

これは、先程のサブクラスの継承を無しにして、なおかつトップレベルのものは参照されなくなります。

なので、railsでクラス間の値を共有したい場合は、class_attributeを使いましょう。

railsguides.jp

以上です。