永井@知能.九工大です.

From: sheepman <sh / sheepman.sakura.ne.jp>
Subject: [ruby-dev:35190] Re: [BUG] class variable
Date: Sat, 21 Jun 2008 09:14:24 +0900
Message-ID: <20080621091653.3a5514f8.sh / sheepman.sakura.ne.jp>
> これは特異メソッドではなくて、クラス変数のスコープの問題だと思います。

あぁ,なるほど.そういうことなんですか.
でも,それって言語仕様としてどうなんでしょう?
以下のようになるということですよね.
------------------------------------------------------
class A
  @ivar = :class_A
  @@cvar = :class_A
  def A.m_A_A
    p(:@ivar=>@ivar, :@@cvar=>@@cvar)
  end
  def A.set_var_A
    @ivar = :mod_A_A
    @@cvar = :mod_A_A
  end
end
class B
  @ivar = :class_B
  @@cvar = :class_B
  def A.m_B_A
    p(:@ivar=>@ivar, :@@cvar=>@@cvar)
  end
  def A.set_var_B
    @ivar = :mod_B_A
    @@cvar = :mod_B_A
  end
  def B.vars
    p(:@ivar=>@ivar, :@@cvar=>@@cvar)
  end
end

A.m_A_A      #=> {:@ivar=>:class_A, :@@cvar=>:class_A}
A.m_B_A      #=> {:@ivar=>:class_A, :@@cvar=>:class_B}
B.vars       #=> {:@ivar=>:class_B, :@@cvar=>:class_B}

A.set_var_A
A.m_A_A      #=> {:@ivar=>:mod_A_A, :@@cvar=>:mod_A_A}
A.m_B_A      #=> {:@ivar=>:mod_A_A, :@@cvar=>:class_B}
B.vars       #=> {:@ivar=>:class_B, :@@cvar=>:class_B}

A.set_var_B
A.m_A_A      #=> {:@ivar=>:mod_B_A, :@@cvar=>:mod_A_A}
A.m_B_A      #=> {:@ivar=>:mod_B_A, :@@cvar=>:mod_B_A}
B.vars       #=> {:@ivar=>:class_B, :@@cvar=>:mod_B_A}
------------------------------------------------------
クラスとしては直接には関係のない A と B との間で
クラス変数が共有されてしまうことになるわけですよね.

A と B との間だけであれば,コード上で関係が直接見えるだけ
まだマシなのですが,さらに class C < A; end とすると
コード上では非常に分かりにくい形で
B と C との間でクラス変数が共有されてしまうことになります.
クラス B からでは inherited メソッドなどで 
hook して捉えることなどもできませんし,
クラス C からも B との間に依存関係があるというのは
コードからは直接には見えません.

現状はバグの温床となる仕様だよなぁと思います.
-- 
永井 秀利  (nagai / ai.kyutech.ac.jp)
九州工業大学 大学院情報工学研究院 知能情報工学研究系