Effective Rubyの勉強メモです。
インスタンス変数とクラス変数
クラス内で@
が先頭につく変数はインスタンス変数を表します。
インスタンス変数はオブジェクト一つ一つが持つプライベートな変数です。オブジェクトのあるインスタンス変数に値をセットしてもほかのオブジェクトのインスタンス変数には影響を及ぼしません。
特別な変数にクラス変数というものもあります。@@
が先頭につく変数で、クラスで一つの値を持ち、そのクラスのインスタンスすべてで共有されます。
もちろん、クラス変数の値を更新すると、すべてのインスタンス変数が更新後の値を使うようになります。
クラス変数を使う一般的な用途の一つにシングルトンがあります。
スポンサーリンク
クラス変数を使ってシングルトンを実装する例
シングルトンとは、システム全体にわたってただ一つのインスタンスしか存在しないようにするデザインパターンです。
例えば設定やデータベースなどを表すインスタンスです。ある個所で設定を変えるとほかの場所でも変更後の設定を見たいですよね。
こんなときに複数のインスタンスがコード中に存在していると、変更されていない古い設定を使うことになります。このような場合に、ただ一つのインスタンスを見るようにシングルトンパターンにするのです。
では実際にクラス変数を使ってシングルトンを実装してみたいと思います。
class Singleton private_class_method(:new, :dup, :clone) def self.instance @@instance ||= new end end
def self.instance
によってクラスメソッドが定義されています。このメソッドは、インスタンスが存在しなければnewメソッドでインスタンスを作りクラス変数に入れ、存在していればそのインスタンスを返すメソッドです。
また、外部から新しくインスタンスを作られないように、新しくインスタンスを作るメソッドをprivate_class_methodメソッドでプライベートメソッド化しています。
これでシングルトンの金型ができました。
では、Singletonクラスを継承して、設定クラスとデータベースクラスを実装していきます。
class Configuration < Singleton end class Database < Singleton end
それぞれのクラスのinstanceメソッドを使ってみます
Configuration.instance #=> #<Configuration:0x00000003442c28> Database.instance #=> #<Configuration:0x00000003442c28>
ここで想定とは異なる動きをしています。
Database.instanceがConfigurationクラスのクラス変数を使っているのです。
ちなみに、この状態で
Singleton.instance #=> #<Configuration:0x00000003442c28>
となってしまいます。
つまり、クラス変数は親クラスを通して兄弟クラス(親が同じクラス)にまで伝搬してしまうのです。
クラスインスタンス変数
そこで対応策としてクラスインスタンス変数を導入しましょうということです。
以前の記事にも書きましたが、クラスもClassクラスのインスタンスなのでインスタンス変数を持つことができます。
class Singleton private_class_method(:new, :dup, :clone) def self.instance @instance ||= new end end
4行目が変わりました。
クラスが持つインスタンス変数なのでクラスインスタンス変数と呼びます。
インスタンス変数なのでもちろん別のクラスとはプライベートになっており、伝搬することもありません。

- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る

Ruby on Rails 5アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/14
- メディア: 大型本
- この商品を含むブログを見る

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る