特異メソッドと特異クラス
特定のオブジェクトのためだけのメソッドやクラス、という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
オブジェクト)」 という点を理解することでピンときた。