QA@IT

Rubyのクラス変数とクラスインスタンス変数の違いと使い所

2336 PV

クラス変数とインスタンス変数は分かりやすいのですが、クラスインスタンス変数の存在理由がよく分かりません。

  • クラス変数
  • クラスインスタンス変数

の違いと、それぞれの使い道を、どなたか教えていただけませんでしょうか。

回答

クラスインスタンス変数はクラス変数的な役割だけど継承されては駄目な場合に使う感じですかね。

とりあえず思いついたサンプル書いてみました。

class Entry < ActiveRecord::Base
  def self.very_heavy_method
    @cache_very_heavy_task ||= self._very_heavy_method
  end
end

class LimitEntry < Entry
  #特定のフラグがついてるEntryだけを検索条件とするコードが入ってるものとする
end

Entry.very_heavy_method
LimitEntry.very_heavy_method
#クラス変数にキャッシュしてるとLimitEntry側でもキャッシュされたことになってしまいますよね

LimitEntry側でEntryのクラスインスタンス変数が参照されちゃったらまずい例です。

編集 履歴 (0)
  • 私もこういう理解です。Eloquent Ruby (http://www.amazon.com/gp/product/0321584104/) のChap.13..14あたりにもこのトピックがあって、だいぶ参考になりました。 -
  • Chapter 14に、RailsのActiveRecordではコールバック関連のメソッド(名)は、@after_save_callbacks のようなクラスインスタンス変数として実装されているとありました(いま読みました)。なるほどー -

クラスもオブジェクトである以上インスタンス変数もあって当たり前だし、
あえてインスタンス変数を禁止する理由もないからあるのでしょう。
さらっとないものとしてスルーするか、クリエイティブな使い方を創造して足を撃ってみるか、
西村さんの腕の見せ所です。

編集 履歴 (0)
  • 禁止する理由もないからある! ほぇぇぇ、なるほど。 -

この記事がそのものずばりでした。

クラスインスタンス変数とは、

クラス変数とほぼ同じだが、そのクラスのみでしか参照できない変数のこと。例えば、そのクラスを継承したクラスではその変数にはアクセスできない。

ということだそうです。

編集 履歴 (1)
  • 私もCの経験が長かったので、この記事の筆者さん同様「変数宣言するのは当たり前だろ?」と思っていたので、きちんと理解しないまま書いていました。修行が足りてませんね! -
  • ありがとうございます。クラスインスタンス変数は、名前通りClassクラスのインスタンスにある変数ですよね。という挙動はまあ分かるのですが、どうも使い道がよく分かりません。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。