JQ Blog

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

前回のポスト(クラスとインスタンスの違い)の続きでクラス変数、インスタンス変数及びMix-inの使い方についてまとめてみる。

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

クラス変数

1
2
3
4
5
6
class Foo
  @@foo = 1
  def bar
    puts @@foo
  end
end

@@で始まる変数はクラス変数である。クラス変数はクラス定義の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/代入ができる。
クラス変数は

  • サブクラスから参照/代入が可能
  • インスタンスメソッドから参照/代入が可能

クラス変数は、そのクラスやサブクラスのインスタンスで共有され、グローバル変数のように使える。

定義

1
@@foo = 1

使い方

1
2
3
4
5
6
7
8
9
class Foo
  @@foo = 1
end
class Bar < Foo
  p @@foo += 1 # => 2
end
class Baz < Bar
  p @@foo += 1 # => 3
end

モジュールで定義されたクラス変数(モジュール変数)は、そのモジュールをインクルードしたクラス間でも共有される。

1
2
3
4
5
6
7
8
9
10
11
module Foo
  @@foo = 1
end
class Bar
  include Foo
  p @@foo += 1 # => 2
end
class Baz
  include Foo
  p @@foo += 1 # => 3
end

インスタンス変数

@で始まる変数はインスタンス変数であり、これはオブジェクトに所属している。
明示的にインスタンス変数を宣言しなくて良い。

  • インスタンス変数にアクセスできるのは、initializeメソッドとオブジェクトのインスタンスメソッドだけ
    • initializeメソッドで初期化されて、その後各インスタンスメソッドから参照・変更

定義

1
@foo = 'foo'

使い方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Foo
  # initializeメソッドからアクセス
  def initialize(foo)
    @foo = foo
    p "#{@foo} が初期化されました。"
  end

  # インスタンスメソッドからアクセス
  def bar
    p "barメソッドから #{@foo} がプリントされました。"
  end

  # クラスメソッドからアクセス
  def self.foobar
    p @foo
  end
end

# initializeメソッドからはアクセスできる
foo = Foo.new("foo") # => 'foo が初期化されました。'

# 各インスタンスごとに違う値を持つことができる
foo2 = Foo.new("bar") # => 'bar が初期化されました。'

# インスタンスメソッドからもアクセスできる
foo.bar # => 'barメソッドから foo がプリントされました。'
foo2.bar # => 'barメソッドから bar がプリントされました。'

# クラスメソッドからはアクセスできない
Foo.foobar # => nil

attr_accessorの書き方
上記のクラスにattr_accessorを定義するとさらに使いやすくなる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo
  # attr_accessorを定義する
  attr_accessor :foo

  # initializeメソッドからアクセス
  def initialize(foo)
    @foo = foo
    p "#{@foo} が初期化されました。"
  end

  # インスタンスメソッドからアクセス
  def bar
    p "barメソッドから #{@foo} がプリントされました。"
  end

  # クラスメソッドからアクセス
  def self.foobar
    p @foo
  end
end

こういうふうに定義すると

1
2
3
4
foo = Foo.new("foo1") # => 'foo1 が初期化されました。'
foo.bar # => 'barメソッドから foo1 がプリントされました。'
foo.foo = "foo2" # => 'foo2'
foo.bar # => 'barメソッドから foo2 がプリントされました。'

のように使える。

参照

【まとめ】インスタンス変数、クラス変数、クラスインスタンス変数
class Class - Ruby 2.3.0 変数と定数