読んだだけじゃ絶対にわすれるので、メモっとく。
特異メソッド
クラスに属するすべてのオブジェクトではなく、単一のオブジェクトだけのために定義されたメソッド
オブジェクトの特異メソッドは、そのオブジェクトのクラスによって定義されない。
そのオブジェクトに対応付けられた無名の特異クラスのインスタンスメソッドである。
無名の特異クラスのことをシングルトンクラス、メタクラスと呼ぶ。
各インスタンスごとに特異クラスを持つ。
classのインスタンスClass1の特異メソッドは、Class1クラスのクラスメソッドであり、
classのインスタンスであるClass1の特異クラスのインスタンスメソッドである。
試してみた。
# ClassクラスのインスタンスであるPointオブジェクトに特異メソッドを定義 # Pointクラスのクラスメソッドになる class Point; end def Point.sum x, y; x + y; end p Point.sum 1,2 #=> 3 # 特異メソッドを複数定義時に便利な構文糖 class << Point def minus x, y; x - y; end def multi x, y; x * y; end end p Point.minus 1,2 #=> -1 p Point.multi 1,2 #=> 2 # クラス定義中にクラスメソッドを複数定義するときに便利な構文糖 # class << self は特異クラス(classのインスタンスであるPointクラスオブジェクト) class Point class << self def div x, y; x / y; end end def self.eignclass class << self; self; end end end # p1オブジェクトの特異メソッドを定義 p1 = Point.new def p1.sum x, y, z; x + y + z; end p p1.sum(1, 2, 3) #=> 6 # p2からはp1の特異メソッドは見えない p2 = Point.new #p p2.sum(1, 2, 3) #=> NoMethodError class << p2 def sum x, y ,z, a; x + y + z + a; end def multi x, y ,z, a; x * y * z * a; end end p p2.sum 1, 2, 3, 4 #=> 10 p p2.multi 1, 2, 3, 4 #=> 24 # p2からはP1特異メソッド特異メソッドは見えない #p p1.sum 1, 2, 3, 4 #=> NoMethodError # 実行結果 # 3 # -1 # 2 # 6 # 10 # 24
もう一丁。
class Class1 puts "#{self.__id__} before open singleton class" class << self puts "#{self.__id__} opening singleton class" end def self.eignclass class << self; self; end end puts "<<< " + self.to_s end class Class2 puts ">>> " + self.to_s puts "#{self.__id__} before open singleton class" class << self puts "#{self.__id__} opening singleton class" end def self.eignclass class << self; self; end end puts "<<< " + self.to_s end puts "------------" puts "#{Class1.__id__} Class1.__id__" puts "#{Class1.eignclass.__id__} Class1.eignclass.__id__" puts "------------" puts "#{Class2.__id__} Class2.__id__" puts "#{Class2.eignclass.__id__} Class2.eignclass.__id__" puts "------------" c1 = Class1.new puts "#{c1.__id__} c1's id" class << c1 puts "#{self.__id__} c1's singleton class" end puts "------------" c11 = Class1.new puts "#{c11.__id__} c11's id" class << c11 puts "#{self.__id__} c11's singleton class" end puts "------------" c2 = Class2.new puts "#{c2.__id__} c2's id" class << c2 puts "#{self.__id__} c2's singleton class" end puts "------------" c21 = Class2.new puts "#{c21.__id__} c21's id" class << c21 puts "#{self.__id__} c21's singleton class" end # 実行結果 # >>> Class1 # 70227334526040 before open singleton class # 70227334526020 opening singleton class # <<< Class1 # >>> Class2 # 70227334525980 before open singleton class # 70227334525680 opening singleton class # <<< Class2 # ------------ # 70227334526040 Class1.__id__ # 70227334526020 Class1.eignclass.__id__ # ------------ # 70227334525980 Class2.__id__ # 70227334525680 Class2.eignclass.__id__ # ------------ # 70227334525100 c1's id # 70227334525040 c1's singleton class # ------------ # 70227334524940 c11's id # 70227334524880 c11's singleton class # ------------ # 70227334524780 c2's id # 70227334524720 c2's singleton class # ------------ # 70227334524620 c21's id # 70227334524560 c21's singleton class
No comments:
Post a Comment