はじめに
この記事は書籍「プロを目指す人のためのRuby入門」に掲載できなかったトピックを著者自らが紹介するアドベントカレンダーの20日目です。
本文に出てくる章番号や項番号は書籍の中で使われている番号です。
今回は特異メソッドと特異クラスの関係について説明します。
必要な前提知識
「プロを目指す人のためのRuby入門」の第7章まで読み終わっていること。
特異メソッドが定義されているクラスはどこ?
Rubyのメソッドは必ず何らかのクラスに定義されています。特異メソッドもその例外ではありません。特異メソッドはインスタンスそのものにメソッドが定義されているようには見えますが、実はそうではなく、特異クラスと呼ばれる特殊なクラスに定義されています。さらに、この特異クラスのスーパークラスは、特異メソッドを定義したインスタンスが属するクラスになっています。
特異メソッドが定義されている特異クラスと、その特異クラスのスーパークラスを確認するコード例を以下に示します。
alice = 'I am Alice.'
# shuffleという特異メソッドを定義する
def alice.shuffle
chars.shuffle.join
end
# 以下のコードの戻り値が、shuffleメソッドが定義されている特異クラス
alice.singleton_method(:shuffle).owner #=> #<Class:#<String:0x007fcd10826948>>
# 上の特異クラスのスーパークラスはStringクラス
alice.singleton_method(:shuffle).owner.superclass #=> String
# このインスタンスが属する特異クラスを確認すると、2つ上に出てきた特異クラスと全く同じ
alice.singleton_class #=> #<Class:#<String:0x007fcd10826948>>
上の結果からわかる内容をクラス図で表すと、次のようになります。
特異クラスはふだん表に出てこないため、その存在に気づくことはほとんどありません。ですが、このように特異メソッドはそのインスタンスのためだけに存在する特異クラスに定義されているのです。
次回予告
次回は第9章の例題で使用した「正規表現チェッカープログラム」のテストを自動化する方法を紹介します。