特異クラスへのアクセス
先述のように、すべてのオブジェクトは自身の特異クラスを持ちます。この特異クラスを拡張 (例えばインスタンスメソッドを追加するなど) したいときはどうすれば良いでしょうか。 特異クラスには名前が与えられていないため、普通のクラスのように class 特異クラス名 ... end
という構文でアクセスすることは出来ません。
その代わりに使うのが、 class << オブジェクトA ... end
という構文です。<<
で開いたスコープ内部では、コンテキストがオブジェクトAの特異クラスへと切り替わっています。
def obj.hi
で定義しても、上記のように<<
で特異クラスを開いてメソッドを定義しても、結果は同じです。
クラスはオブジェクトである
ここで少し余談として、Rubyが「クラス」をどう扱っているか復習します。
Rubyにおいて、(ほぼ)すべてはオブジェクトです。クラスも例外ではなく、オブジェクトです。正確に言うと "Class" という名前のクラスが上位に存在し、StringやArrayやIntegerといったクラス、また自身で定義したHogeクラスなども、すべて"Class"クラスのインスタンスとして生成されます。
クラスもオブジェクトであるということは、もちろん特異クラスを持っているはずです。<<
でオープンし、特異メソッドを追加することが出来ます。
最後の String.shout
は特異クラスの呼び出しですが、クラスメソッドの呼び出しのように見えます。事実、クラスメソッドと呼ばれているものは特異メソッドの一種です。
クラスメソッドは特異メソッドの一種である
特異クラス・特異メソッドの知識を得たうえでRubyのクラスメソッド定義を見てみます。
クラス定義中にclass << self ... end
と書くのはクラスメソッドを定義する際によく使われるイディオムで、def self.method_name
としても結果は同じです。
以上
以上で特異クラス・特異メソッドの説明は終わりです。