Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
self / クラスメソッド / インスタンス変数 / クラス変数
Rubyの『self』キーワードと、インスタンス変数(@)・クラス変数(@@)の使い方を解説します。クラスメソッドの定義にも『self』を使います。
構文
class クラス名
# クラス変数: すべてのインスタンスで共有されます。
@@クラス変数 = 初期値
def initialize
# インスタンス変数: 各インスタンス固有のデータです。
@インスタンス変数 = 値
end
# インスタンスメソッド内の self: そのインスタンス自身を指します。
def instance_method
self # このインスタンス自身を返します。
self.メソッド名 # 自分自身にメソッドを呼び出します。
end
# クラスメソッドの定義: def self.メソッド名 と書きます。
def self.クラスメソッド名
処理 # ここでの self はクラス自身を指します。
end
end
# クラスメソッドの呼び出し。
クラス名.クラスメソッド名
メソッド一覧
| 構文 | 概要 |
|---|---|
| self(インスタンスメソッド内) | そのメソッドを呼び出されたインスタンス自身を指します。 |
| self(クラス定義内のトップレベル) | クラス自身を指します。クラスメソッドの定義に使います。 |
| def self.メソッド名 | クラスメソッドを定義します。インスタンスなしで『クラス名.メソッド名』で呼び出せます。 |
| @変数名 | インスタンス変数です。各インスタンスが独自に持つデータです。 |
| @@変数名 | クラス変数です。同じクラスのすべてのインスタンスと共有されます。 |
サンプルコード
class Counter
# クラス変数: 全インスタンスで共有します。
@@total = 0
attr_reader :count, :name
def initialize(name)
@name = name # インスタンス変数: このインスタンスだけの値。
@count = 0
@@total += 1
end
def increment
@count += 1
self # self を返すとメソッドチェーンが可能になります。
end
def info
"#{@name}: #{@count}回(合計インスタンス数: #{@@total})"
end
# クラスメソッド: インスタンスなしで呼び出せます。
def self.total
@@total
end
# クラスインスタンス変数: クラス変数より安全です(継承しても独立)。
@description = "カウンタークラス"
def self.description
@description
end
end
a = Counter.new("カウンターA")
b = Counter.new("カウンターB")
# インスタンスメソッドの呼び出し。
a.increment.increment.increment # self を返すのでチェーンできます。
b.increment
puts a.info # カウンターA: 3回(合計インスタンス数: 2)
puts b.info # カウンターB: 1回(合計インスタンス数: 2)
# クラスメソッドの呼び出し。
puts Counter.total # 2
puts Counter.description # カウンタークラス
概要
『self』はコンテキストによって指すものが変わります。インスタンスメソッド内では「そのインスタンス自身」を、クラス定義のトップレベルでは「クラス自身」を指します。インスタンスメソッドで『self』を返すことで、メソッドチェーンが可能になります。
クラス変数(『@@』)は便利ですが、継承したサブクラスと共有されるため意図しない挙動が起きることがあります。そのため「クラスインスタンス変数(クラスのトップレベルで定義した『@変数』)」を使う方が安全です。クラスインスタンス変数はクラスメソッド内の『@変数』でアクセスします。
インスタンスメソッド内でインスタンス変数名を打ち間違えた場合(例: 『@nmae』)、Rubyはエラーを出さずに『nil』を返します。デバッグが困難になるため、タイポに注意してください。
クラスの基本定義は『class / initialize / attr_accessor』を、モジュールとミックスインは『module / include / extend』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。