ruby書いているとタイトルのような記述を見たことがある人は多いとおもいます。自分はよくわからなかったので今回の記事でまとめてみようとおもいます。
こういう時はとりあえず公式ドキュメントを見てみようと思ったので見てみました。すると、
特異クラス方式。複数のメソッドを一度に定義するとき向き
https://docs.ruby-lang.org/ja/3.0/doc/spec=2fdef.html#class_method
特異メソッドとは?
特異メソッドとは1つのオブジェクトに対して適用されるメソッドのことです。実際に例を見ていきましょう
class User
def my_name
puts "自己紹介しましょう"
end
end
ouki = User.new
riboku = User.new
def ouki.introduction
p "秦国最強の将軍である"
end
ouki.my_name
=> 自己紹介しましょう
riboku.my_name
=> 自己紹介しましょう
ouki.introduction
=> "秦国最強の将軍である"
riboku.introduction
NoMethodError (undefined method `introduction' for #<User:0x000002364158c3b0>)
rubyではメソッドは、def メソッド名 end
と記述します。
my_nameはインスタンスメソッドです。そのため、Userクラスから作成されたoukiインスタンスやribokuインスタンスではmy_nameメソッドが使えます。
しかし、ouki.introductionメソッドは違います。これは、oukiインスタンスしか使えないメソッドなんです。そのため、ribokuインスタンスがそのメソッドを使うとしてもエラーを吐くわけです。
あるオブジェクトにのみ適用できる特別に異なるメソッド、それが特異メソッドです。
特異メソッドの実態
rubyの原則として、メソッドはクラスに紐づくというものがあります。そのため特異メソッドもなんかしらのクラスに属しているはずなんですね。実際にどこのクラスに属しているのかを見ていきましょう。
class User
def my_name
puts "自己紹介しましょう"
end
end
ouki = User.new
riboku = User.new
def ouki.introduction
p "秦国最強の将軍である"
end
p ouki.class.method_defined?(:introduction)
=> false
p ouki.singleton_class.method_defined? :introduction
=> true
上記からも分かるように、ouki.introductionメソッドという特異メソッドは、Userクラスに属しているのではなく、特異クラスに属していることが分かります。なお、特異クラスは特異メソッドが定義されたときに自動で作成されます。
つまり、特異クラスに特異メソッドは属しているということです。
クラスに特異メソッドを定義してみましょう
class User
def User.introduction(name)
p "#{name}"
end
end
puts User.introduction("王騎")
=> 王騎
このintroductionメソッドの呼び出し方は、クラスメソッドの呼び出し方と同じなんです。つまり、
class User
def self.introduction(name)
p "#{name}"
end
puts self.introduction('王騎')
end
これと同じなんです。
ここからわかることは、クラスメソッドはクラスの特異メソッドにあたるんです。
class<<selfとは?
これは特異クラス定義式といいまして、そのまんまの意味です。特異クラスを定義するものです。ここまで読んだ方であれば、特異クラスとは特異メソッドを定義した時にでてくるものでしたね。
実際に特異クラス定義式で書いてみましょう
class User; end
class << User
def production(name)
puts "#{name}"
end
end
puts User.production('王騎')
=> 王騎
class << User
でUserの特異クラスに対して、Userの特異メソッドを定義しています。
さらにUserの部分をselfに変えてあげれば、
class User; end
class << self
def production(name)
puts "#{name}"
end
end
puts User.production('王騎')
=> 王騎
今回のタイトルの形ができましたね。
まとめると、class << self
は特異クラスにたいして特異メソッドを定義しているんです。
以上です。何か間違いがございましたら、ご教示いただけますと幸いです。
【参考資料】