前回のポスト(クラスとインスタンスの違い)の続きでクラス変数、インスタンス変数及びMix-inの使い方についてまとめてみる。
クラス変数、インスタンス変数
クラス変数
1
2
3
4
5
6
| class Foo
@@foo = 1
def bar
puts @@foo
end
end
|
@@で始まる変数はクラス変数である。クラス変数はクラス定義の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/代入ができる。
クラス変数は
- サブクラスから参照/代入が可能
- インスタンスメソッドから参照/代入が可能
クラス変数は、そのクラスやサブクラスのインスタンスで共有され、グローバル変数のように使える。
定義
使い方
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
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 変数と定数