rubyにおけるクラスメソッド・インスタンスメソッドについて初心者向けに
ざくっと書いていきます。
プログラミング初めたての頃は「クラス」「インスタンス」「オブジェクト」・・・
と横文字がたくさん出てきて一瞬パニクり、さらにクラスメソッドとかいう
謎な言葉が出てくると嫌になりますよね。。。
でも、知ってしまえば「そんなことか」と思えるので今回はざっくりと説明します。
以下のコードを実行してみると違いが一発で分かります。
class Hoge
# インスタンスメソッドの定義
def hoge
p "インスタンスメソッド呼び出し成功"
end
# クラスメソッドの定義
def self.fuga
p "クラスメソッド呼び出し成功"
end
end
#インスタンスメソッドの呼び出し
Hoge.new.hoge
#インスタンスメソッドの呼び出しに失敗する
begin
Hoge.hoge
rescue
p "インスタンスメソッド呼び出し失敗"
end
#クラスメソッドの呼び出し
Hoge.fuga
#クラスメソッドの呼び出しに失敗する
begin
Hoge.new.fuga
rescue
p "クラスメソッド呼び出し失敗"
end
以上の結果から、
**クラスメソッドはクラスオブジェクトから呼び出すことができるが、
インスタンスオブジェクトからは呼び出せない。
インスタンスメソッドはインスタンスオブジェクトから呼び出すことができるが、
クラスオブジェクトからは呼び出せない。 **
ということが分かります。
もう少し詳しく見ていきましょう
インスタンスメソッド
def hoge
p "インスタンスメソッド呼び出し成功"
end
rubyを少しでも書いたことがあるなら見覚えはあると思います。
いわゆるメソッドを定義していますね。
何の気なしに書いてきましたが、実はこれはインスタンスメソッドを定義しています。
その名の通りインスタンスメソッドはインスタンスからのみ実行できます。
これだけ覚えておけばインスタンスメソッドについては十分です。
# newされているのでインスタンスオブジェクトからメソッドを呼び出している
Hoge.new.hoge
# クラスオブジェクトからは呼び出せない
Hoge.hoge
クラスメソッド
def self.fuga
p "クラスメソッド呼び出し成功"
end
クラスメソッドには戸惑う方もいるかもしれません。
それも全てこのselfのせい。
selfについて今説明するとややこしくなるので詳細には書きません。
この場合selfはHogeクラスを指します。
ですので
def Hoge.fuga
p "クラスメソッド呼び出し成功"
end
と書いても一緒です。
現段階ではこのような書き方のメソッドをクラスメソッドと認識しても問題ないかと思います。
※ただし、下記のようにメソッドの中でselfが使われてる場合はクラスメソッドではありませんので
注意してください。
def piyo
self.hoge
end
ちょっとややこしいかもしれませんがこれは
メソッドpiyoを実行したインスタンスオブジェクトに定義されているhogeメソッドを実行する
という意味になります。
selfはメソッドが呼び出されたオブジェクトを表しているんだなぁという理解でOKだと思います。
(この辺は別で詳細書きます)
まとめるとクラスメソッドはクラスオブジェクトからしか実行できず、
def self.メソッド名
def クラス名.メソッド名
の形式で書かれたメソッドだと覚えておけば十分でしょう。
クラスメソッドとインスタンスメソッドの使い分け
この辺りはクラス設計のお話なのでなかなか難しいところで、意見が分かれるかもしれないので
あくまで一個人の考えとして捉えてください。
基本的にはインスタンスメソッドで全てまかなってみるというのが根本的思想のように思います。
では、クラスメソッドはいつ使えばいいのかですが、これは
新しいインスタンスを生成するときに使われることが多い印象です。
単純なwhereやfindでは作れない複雑な条件を書くときはクラスメソッドで記述して、
それをコントローラで呼び出すということがよく行われている気がします。
まとめ
色々書きましたが
**クラスメソッドはクラスオブジェクトから呼び出すことができるが、
インスタンスオブジェクトからは呼び出せない。
インスタンスメソッドはインスタンスオブジェクトから呼び出すことができるが、
クラスオブジェクトからは呼び出せない。 **
これだけ覚えておけば初心者のうちはとりあえずOKかと思います。
なんとなくわかってきたら特異メソッドとかについて調べてみると面白いかもしれませんね。