はじめに

クラスの使い方がだんだん分かってきましたか?
ここまで、クラスとサブクラス、インスタンス変数、インスタンスメソッドについて学んできました。
最後に、クラスが持てる「クラス変数」と「クラスメソッド」について学習しましょう。
これは、インスタンス変数やメソッドとは性質の異なるものです。
この記事では、Ruby初心者の方向けに、クラスのクラス変数とクラスメソッドについてお伝えしていきます。
インスタンス変数やメソッドとの違いをよく理解しておきましょう。

インスタンス変数とインスタンスメソッドのおさらい

はじめに、これまで学んできたインスタンス変数とインスタンスメソッドについておさらいしておきます。
Rubyでは、次のように定義するのでした。
例:

class Square
    def initialize(length)
        @length = length
    end
    def printArea
        puts @length * @length
    end
end

この例では、インスタンス変数として”@length”、インスタンスメソッドとして”printArea”を定義しています。
インスタンス変数およびメソッドはオブジェクトに属しています。
このため、次のように複数のオブジェクト(インスタンス)を作っても、互いに独立していることがわかります。
例:

s1 = Square.new(5)
s2 = Square.new(8)
s1.printArea
s2.printArea

このように、同じクラスから生成されたオブジェクトでも、それぞれ固有のインスタンス変数を持ちます。
また、インスタンスメソッドがアクセスできる変数も、自らが属するオブジェクトのものだけです。
これは重要なことなので覚えておきましょう。
しかし、次に説明するクラス変数とクラスメソッドでは事情が異なります。

クラス変数とクラスメソッドとはなにか?

インスタンス変数およびメソッドがオブジェクトに属するのに対し、クラス変数およびメソッドはクラスに属しています。
つまり、クラス変数およびメソッドはクラス全体で共有されているわけです。
どういうことか、コードを書いて確かめてみましょう。

クラス変数とクラスメソッドを持たせてみよう

ここでは、クラス変数とクラスメソッドの使用例として、オブジェクトが生成された数をカウントするクラスを考えてみます。
たとえば、次のような実装が考えられます。
例:

class Counter
    def initialize
        if defined?(@@count)
            @@count += 1
        else
            @@count = 1
        end
    end
    def self.count
        @@count
    end
end

いろいろと新しい要素が出てきました。ひとつずつみていきましょう。
まずは、”initializeメソッド”に注目して下さい。
ここでは、オブジェクトが生成されるごとにクラス変数”@@count”をカウントアップしています。
初回はまだクラス変数が存在しないため、if文と”defined?メソッド(変数が存在しなければnil、つまり偽になる)”を組み合わせて処理を分けています。
このクラス変数(@@count)は、すべてのオブジェクト(インスタンス)で共有されます。
残りは、クラスメソッドである”count”です。
クラスメソッドを定義するには、例のようにメソッド名の前に”self.”をつけます。
こうするとメソッドがクラスに属することになり、インスタンスからはアクセスできなくなります。
どういうことか、実際に使ってみましょう。
例:

c1 = Counter.new
puts Counter.count
c2 = Counter.new
c3 = Counter.new
puts Counter.count

オブジェクトを生成する度にカウントアップしていくことが確認できますね。
注目してほしいのは、”Counter.count”です。オブジェクトではなく、クラスから直接呼び出されていますね。
このように、クラスメソッドはクラス名を使って呼び出す必要がありますので注意しましょう。

どのような用途に使うべきなのか?

クラス変数やクラスメソッドを使う機会は頻繁にはないかもしれませんが、覚えておけば必ず役に立ちます。
たとえば、次のようにシングルトンパターンを実装するためにも使えます。
例:

class Singleton
    @@instance = Singleton.new
    def self.instance
        @@instance
    end
    private_class_method :new
end
s1 = Singleton.instance
s2 = Singleton.instance
puts "同じオブジェクトです" if s1.equal?(s2)

シングルトンパターンは、クラスのただひとつのインスタンス(オブジェクト)のみが存在することを保証するための方法です。
クラス変数に唯一のオブジェクトを保持することで、常に同じオブジェクトを返すようにしています。
また、”private_class_methodメソッド”を使って、自身の”newメソッド”を呼び出せないようにしています。

まとめ

クラス変数とクラスメソッドの使い方がお分かりになりましたか?
クラス変数およびメソッドはクラスに属し、インスタンス変数およびメソッドはオブジェクトに属することを覚えておきましょう。
それぞれ用途が異なります。
両方を正しく使い分けられるようになりましょう。