特異メソッドと特異クラス
特定のオブジェクトのためだけのメソッドやクラス、というRubyの概念。
特異メソッド
- 特異メソッド
build_greetingは、定義時に変数messageが参照していた文字列オブジェクトにだけ属する。
message = "Hello" # 文字列オブジェクト
def message.build_greeting(target)
"#{self}, #{target}."
end
message.build_greeting("world") # => Hello, world.
message2 = "Hello" # 値は同じだが異なるオブジェクト
message2.build_greeting("world") # => NoMethodError
Singletonパターン
- そのクラスのインスタンスが1つしか生成されないことを保証するGoFのデザインパターン。
CENTRAL_REPOSITORY = Object.new
def CENTRAL_REPOSITORY.register(target)
@registered_objects ||= []
unless @resgistered_objects.include? target
@registered_objects << target
end
end
def CENTRAL_REPOSITORY.unregister(target)
@registered_objects = []
@registered_objects.delete(target)
end
特異クラス
- 特異クラスの定義式は、
class式において「<<(オブジェクト)」と記述する。- オブジェクト
CENTRAL_REPOSITORYは、特異クラス(CENTRAL_REPOSITORY)に属するようになる。 - 特異クラス
(CENTRAL_REPOSITORY)に追加されたインスタンスメソッドは、オブジェクトCENTRAL_REPOSITORYに対して呼び出すことができる。
- オブジェクト
CENTRAL_REPOSITORY = Object.new
class << CENTRAL_REPOSITORY
def register(target)
@registered_objects ||= []
unless @registered_objects.include? target
@registered_objects << target
end
end
def unregister(target)
@registered_objects ||= []
@registered_objects.delete(target)
end
end
特異メソッドとの関係
-
特異メソッドとは、特異クラスのインスタンスメソッド のこと。
- つまり上記2つの例で起きていることは同じ。
クラスメソッド とメタクラス
-
クラスメソッドとは、
Classオブジェクトの特異メソッド のこと。 -
疑似変数
selfはDuration自体を参照しているので、a_week_fromはDurationの特異メソッド。
class Duration
def self.a_week_from(from)
return self.new(from, from+7*24&60*60)
end
end
p Duration.a_week_from(Time.now)
メタクラス
-
メタクラスとは、
Classオブジェクトの特異クラス のこと。 -
特異クラス
(Duration)のことを、Durationのメタクラスとも呼ぶ。
class Duration
class << self # self(=Duration)の特異クラスを定義
def a_week_from(from)
return self.new(from, from+7*24*60*60)
end
end
end
p Duration.a_week_from(Time.now)
まとめ
「AクラスのクラスはClassクラス( = AクラスはClassオブジェクト)」 という点を理解することでピンときた。