LoginSignup
3
3

More than 5 years have passed since last update.

Rubyでのインスタンス変数とクラス変数の扱いについて

Last updated at Posted at 2015-07-16

Rubyでのインスタンス変数とクラス変数の扱いについて

いきなりコード。

class Access
  def initialize
    # インスタンス変数を初期化
    @instance = "Access instance var"
    # クラス変数を初期化
    @@class = "Access class var"
  end

  def self.test
    p @instance
    p @@class
  end

  def test
    p @instance
    p @@class
  end
end

obj = Access.new

p "--CLASS--"
Access.test

p "--INSTANCE--"
obj.test

実行結果がこちら

"--CLASS--"
nil
"Access class var"
"--INSTANCE--"
"Access instance var"
"Access class var"

解説

上記のコード内では、

  1. Accessクラス定義
  2. initializeメソッド定義
  3. testメソッド(クラスメソッド)定義
  4. testメソッド(インスタンスメソッド)定義
  5. Accessクラスのオブジェクト作成
  6. Accessオブジェクトからtestメソッド呼び出し
  7. オブジェクトからtestメソッド呼び出し

という処理を行っています。

Accessクラスのオブジェクトを生成したタイミングで、initializeメソッドにより、インスタンス変数とクラス変数をそれぞれ初期化されます。

それぞれのメソッド内では、初期化したインスタンス変数とクラス変数を呼び出していますが、クラスメソッド内で呼び出したインスタンス変数がnilを返しています。

Rubyのインスタンス変数はそのクラスのオブジェクトごとに別々の値を持ちます。
Rubyはクラスもオブジェクトの一種です。
コード内のself.testメソッドはAccessオブジェクトの特異メソッドという扱いになり、特異メソッド内で呼ばれるインスタンス変数は、Accessオブジェクト内のスコープに属しています。
そのため、クラスメソッド内で呼ばれたインスタンス変数は初期化されていないため、nilを返したというわけです。

ためしに、クラスメソッド内でインスタンス変数を初期化してみます。

class Access
  def initialize
    # インスタンス変数を初期化
    @instance = "Access instance var"
    # クラス変数を初期化
    @@class = "Access class var"
  end

  def self.test
    @instance = "Access class instance var"
    p @instance
    p @@class
  end

  def test
    p @instance
    p @@class
  end
end

obj = Access.new

p "--CLASS--"
Access.test

p "--INSTANCE--"
obj.test

実行結果はこちらです。

"--CLASS--"
"Access class instance var"
"Access class var"
"--INSTANCE--"
"Access instance var"
"Access class var"

クラス内で同じインスタンス変数を用いていますが、別々の値を表示しており、変数のスコープがことなっていることがわかります。

一方、クラス変数は、そのクラスやそのクラスに紐付いたオブジェクトから共通に呼び出すことができるため、問題なく表示されています。

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3