Rubyにはクラスに定義しただけで使えるクラスメソッドが利用できます。ただし普通にメソッドを定義しただけでは、newメソッドでインスタンス化しないと、そのメソッドは利用できません。クラスメソッドとして利用するためには、特別な設定が必要です。
今回はRubyにおけるクラスメソッドの概要とその使い方について解説します。
クラスメソッドとインスタンスメソッドの違い
Rubyでは、クラスの中にメソッドを定義する際、クラスメソッドとインスタンスメソッドの2通りの方法から選べます。なお、通常クラスの中にメソッドを作る場合、それはインスタンスメソッドです。
まずはRubyにおけるメソッドの基本とクラスメソッドとインスタンスメソッドの違いについて解説します。
メソッドの基本
Rubyにおけるメソッドとは、プログラムで利用される処理をひとまとめにしたもので、引数で値を引き渡し、処理の結果を戻り値として返すことが可能です。そして他のプログラミング言語では関数と呼ばれています。
簡単なプログラムであれば同じソースコードにメソッドを記述しますが、別ファイルに用意する場合などではクラスを定義し、その中にメソッドを記述します。そしてクラスの中に定義したメソッドは、通常newメソッドでインスタンス化して呼び出します。
なおRubyではクラス定義もオブジェクトの1つとして扱います。そのためまだインスタンス化していないクラスだとしても、特別な設定を実施したメソッドは、クラス定義のオブジェクトのメソッドとして利用できます。
インスタンス名から参照するインスタンスメソッド
クラス定義をnewメソッドで実体化したものがインスタンスです。クラスをnewメソッドで実体化した場合、インスタンス名が付くので、そのクラス内に定義されたメソッドを呼び出すにはインスタンス名を使って参照します。この方法で呼び出されるメソッドがインスタンスメソッドです。
インスタンスメソッドの書き方
class クラス名 def メソッド名(引数) # メソッドで実行する処理 end end インスタンス名 = クラス名.new インスタンス名.メソッド名(引数)
クラス名から参照するのがクラスメソッド
先ほどインスタンスメソッドの使い方を紹介しましたが、インスタンス名の代わりにクラス名を利用してメソッドを参照する方法がクラスメソッドです。
ただし、クラスメソッドとして使用する場合は、クラス定義のオブジェクトの中のメソッドを利用できるようにするため、メソッド名に「self.」を付けて定義します。なお、「self.」が付いたメソッドはnewメソッドで作ったインスタンスからは利用できないので注意してください。
クラスメソッドの書き方
class クラス名 def self.メソッド名(引数) # メソッドで実行する処理 end end クラス名.メソッド名(引数)
また、クラスメソッドを宣言するには「class << self」を使う方法もあります。
class クラス名 class << self def self.メソッド名(引数) # メソッドで実行する処理 end end end クラス名.メソッド名(引数)
クラスメソッドの使い方とは
先ほど紹介したようにRubyにはクラスメソッドとインスタンスメソッドとがあり、状況に合わせて使い分けることが可能です。ではクラスメソッドはどのような状況で使うのでしょうか。次からクラスメソッドを使うと便利なケースをクラスメソッドの制限について紹介します。
クラス名を直接使える
クラスメソッドの特徴を挙げるとすれば、「クラス名.メソッド名」と記述することから、どのクラスに含まれるメソッドかが解りやすい点です。
例えば、配列のオブジェクトを宣言する場合、下記の例のように記述するとArrayクラスに定義されたnewメソッドによって作られたことが見てすぐ解ります。このようにどのクラスに定義されているメソッドかが解りやすい点がクラスメソッドのメリットです。
d_table = Array.new
初期値を設定できない
独自のクラスを作成した場合、newメソッドインスタンス化する際にその引数で初期値を設定し、それを使ってメソッド内で処理するケースがよくあります。これはインスタンスメソッドでよく使われる方法です。
具体的には、クラスの中に「initialize」というメソッドを定義しておくと、インスタンス化した際に自動でこのメソッドを実行します。またインスタンスした際の引き数をインスタンス変数に設定することで、インスタンス内のどこからで利用できます。
初期値を設定するクラスの例
class Class_A() def initialize(title) @title = title end end
上の例をインスタンス化する例
obj = Class_A.new("Class_A")
上記は、インスタンス化した際にインスタンス変数「@title」に”D_Class”を設定する例です。
しかしクラスメソッドは初期値を設定できません。そのためクラスメソッドは、初期値が不要なケースで利用してください。
クラスメソッドの使用例
先ほども説明したようにRubyではクラスの定義自体がオブジェクトのため、newメソッドでインスタンス化しなくてもクラスメソッドといして利用できます。そして、クラスメソッドとして利用するには、先ほど紹介したようにメソッドを定義する際に、「self.」を付けるか「class << self」から「end」で囲わなければなりません。
次にクラスメソッドの例を用いてクラスメソッドの書き方を紹介します。
self.メソッド名の書き方の例
下記の例は、メソッドを1つだけを含むクラスで、インスタンス化してメソッドを実行できます。
インスタンスメソッドの書き方
class Class_A def class_name() ret = "Class_A" return(ret) end end obj = Class_A.new p obj.class_name() # "Class_A"と表示される
この例をクラスメソッドで書き換えた例が下記の通りです。メソッド名に「self.」を付けることでインスタンスせずにメソッドを利用できます。
self.メソッド名を使った例
class Class_A def self.class_name() ret = "Class_A" return(ret) end end p Class_A.class_name() # "Class_A"と表示される
「class << self」を使った例
クラスメソッドは、「class << self」を使う書き方も可能です。上の例をこの方法で書き直すと、次のようき書けます。class~endがクラスの宣言とクラスメソッドの宣言で二重になっている点に注目してください。
「class << self」を使った例
class Class_A class << self def class_name() ret = "Class_A" return(ret) end end end p Class_A.class_name() # "Class_A"と表示される
クラス変数の設定に利用する例
クラスメソッドを使う場合、先ほど紹介したようにメソッドを定義する際にメソッド名に「self.」を付けるだけです。同じクラスにクラスメソッドとインスタンスメソッドを定義できます。そして、クラスメソッドをインスタンスから呼び出すことはできません。
この機能を利用することで、同じクラスから作られたインスタンスなら同じ変数を参照できるクラス変数を定義し、そのクラス変数をインスタンスメソッドで利用するプログラムが作れます。
クラス変数をクラスメソッドで定義する例
class Class_C @@name = "Class_C" def self.class_name() ret = "Class_C" return(ret) end def self.set_name(name) @@name = name end def show_name() puts @@name end end p Class_C.class_name() Class_C.set_name("TEST") obj1 = Class_C.new obj1.show_name() # TESTが表示される
この例は、クラス変数「@@name」をクラスメソッド「set_name()」で設定し、インスタンスメソッド「show_name」で利用しています。
まとめ
これまで紹介したようにRubyにはクラスとして定義するだけで使えるクラスメソッドがあります。そしてクラスメソッドを利用するにはメソッドに「self.」を付けるか、「class << self」と「end」で囲います。
そしてクラス名を利用するので、どのクラスに記述されたメソッドかが解りすく、機能のみ利用するメソッドでの利用に向いています。クラスからインスタンスを作ってから利用するメソッドとうまく使い分けてください。