ぎょーぼのぶろぐ

IT系の話を書いていくブログです。今はRubyの勉強中。

【Ruby v2.6】クラスメソッド その2(クラスメソッドと特異クラス)

前置き

Ruby のクラスメソッドについてです。その2は、クラスメソッドと特異クラスについて。

クラスメソッド

その1で、クラスメソッドの定義方法は、self.[メソッド名] で定義する、と書きましたが、これは、インスタンスオブジェクトに特異メソッドを定義する場合と同じ書き方 [オブジェクト名].[メソッド名] です。つまり、クラスメソッドは、クラスオブジェクトに対する特異メソッド、ということになります。

サンプル

以下、サンプルのクラスで例を示します。

class A
    # クラスメソッド
    def self.class_method
        p "called self.class_method."
    end
end

まず、通常のクラス A の定義ですが、調べてみると、

A.methods(false)                              # => [:class_method]
A.singleton_class.instance_methods(false)     # => [:class_method]

クラスメソッド class_method は、クラス A のメソッドであると同時に、クラス A の特異クラスのインスタンスメソッド、ということになっています。

「クラスメソッド」と「特異クラス」の関係

図で表現すると、下記のようになります。

f:id:gyobo:20200817220924p:plain

クラスメソッド :class_methodを定義すると、図のようにクラス A の特異クラスのインスタンスメソッドとして、:class_method が格納されます。

クラスメソッドのもう一つの定義方法

クラスメソッドは、特異クラスのインスタンスメソッドです。ですので、クラスメソッドのもう一つの定義方法として、特異クラスに直接、インスタンスメソッドとして定義する方法があります。

class B
    # 特異クラスを開く
    class << self
        # 特異クラスのインスタンスメソッドとして定義する。
        def class_method_2
            p "called class_method_2."
        end
    end
end

このクラスについて確認してみると、

B.methods(false)        # => ":class_method_2]
B.class_method_2        # => "called class_method_2."

確かに、クラス B のクラスメソッドとして定義されています。

その2のまとめ

  • クラスメソッドは、クラスオブジェクトの特異メソッドであり、そのクラスの特異クラスのインスタンスメソッドでもある。
  • クラスメソッドを定義すると、そのクラスの特異クラスに格納される。
  • クラスメソッドの定義方法として、「特異クラス」のインスタンスメソッドとして定義する方法もある。

その3に続きます。