ぎょーぼのぶろぐ

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

【Ruby v2.6】クラスメソッド その1(基本的なこと)

前置き

Ruby のクラスメソッドについてまとめます。 インスタンスメソッドと同じく、その1は、基本的なことを整理します。

書き方

インスタンスメソッドの定義と同じように、クラス定義内で、def の後にメソッド名を書きますが、メソッド名の前にself.をつけて定義します。

クラスメソッドのサンプル

以下、サンプルのクラスです。

class A 
    @@classval = "クラス変数 @@classval"
    @classinsval = "クラスインスタンス変数 @classinsval"

    # 通常のクラスメソッド
    def self.a_method
        @classinsval_a = "クラスインスタンス変数 @classinsval_a"
        p "called self.a_method."
    end

    # self の代わりにクラス名で定義もできる。
    def A.b_method
        @classinsval_b = "クラスインスタンス変数 @classinsval_b"
        p "called A.b_method."
    end

    # 変数表示用のクラスメソッド
    def self.show
        p "@@classinsval = #{@@classval}"
        p "@classinsval = #{@classinsval}"
        p "@classinsval_a = #{@classinsval_a}"
        p "@classinsval_b = #{@classinsval_b}"
    end

end

# クラス A を継承したクラス B (中身は空)
class B < A 
    
end      

irb でクラスを読み込んで、確認してみます。

まず、クラスのメソッドを確認してみます。

A.methods(false)      # => [:b_method, :a_method]         クラス A で定義されたメソッド
B.methods(false)      # => []          クラス B で定義されたメソッドは無い。
B.methods             # => [:b_method, :a_method, ・・・・・]       `false`を指定しなければ表示される。

A.a_method        # => "called self.a_method."
A.b_method        # => "called A.b_method."
B.a_method        # => "called self.a_method."
B.b_method        # => "called A.b_method."

selfを使っても、クラス名Aを使っても同じようにクラスメソッドが定義されています。クラス B でも、継承されたクラスメソッドがそのまま使用できます。

続けて、showメソッドで、変数を確認してみます。(クラス A, クラス B ともに a_method, b_method を実行した状態です。)

A.show
# => "@@classinsval = クラス変数 @@classval"
     "@classinsval = クラスインスタンス変数 @classinsval"
     "@classinsval_a = クラスインスタンス変数 @classinsval_a"
     "@classinsval_b = クラスインスタンス変数 @classinsval_b"

B.show
# => "@@classinsval = クラス変数 @@classval"
     "@classinsval = "
     "@classinsval_a = クラスインスタンス変数 @classinsval_a"
     "@classinsval_b = クラスインスタンス変数 @classinsval_b"

クラス B のクラスインスタンス変数のみ、値が入っていません。これは、クラスインスタンス変数が継承されないためで、代入(初期化)が実行されたクラスインスタンス変数のみ表示されます。

クラスメソッドから、インスタンス変数は参照できません。クラスメソッド内で@変数名と書くと、クラスインスタンス変数と解釈されるためです。

その1のまとめ

  • クラスメソッドは、クラス定義内で def self.[メソッド名] または def [クラス名].[メソッド名]で定義する。
  • クラスメソッドは、[クラス名].[メソッド名]で呼び出す。
  • クラスメソッド内では、クラス変数とクラスインスタンス変数は参照できる。インスタンス変数は参照できない。

その2に続きます。