Class (vol.3 クラスメソッド)

インスタンスメソッド / クラスメソッド

クラスに作るメソッドは 2 種類ある

  1. インスタンスメソッド (インスタンスをレシーバとするメソッド)
  2. クラスメソッド (クラスをレシーバとするメソッド)

インスタンスメソッド

  • レシーバ(. の前に書かれた、メソッドを呼び出すオブジェクト)がインスタンスであるメソッド
    • インスタンスに対して呼び出すメソッド
# インスタンスメソッド
say.name
[1, 2, 3].size
1.even?

クラスメソッド

  • レシーバがクラスであるメソッド
  • インスタンスメソッドと違い、クラス名につづいて呼び出す
  • 例)
    • new メソッドはクラスメソッド
      • Say.new
        • Say クラスの new メソッドを呼び出している
      • Say クラスのオブジェクトを生成する仕事をする
  • クラスに対して呼び出すメソッド
# クラスメソッド
Say.new
String.new
Array.new

クラスメソッドを定義する(その1)

def self.メソッド名
end
class Say
  def self.word(text)
    text
  end
end

p Say.word("Hi")
  • クラスメソッドを定義するには、メソッド名の前に self をつける
  • 呼び出す際は クラス名.メソッド名
  • クラスメソッドは、クラスが実行するのでオブジェクトを作る必要がない
名前インスタンスメソッドクラスメソッド
定義方法def メソッド名def self.メソッド名
呼び出し方法インスタンス.メソッドクラス.メソッド
レシーバインスタンスクラス
ドキュメント記法クラス名#メソッド名クラス名.メソッド名

# 記法 / . 記法

  • インスタンスメソッド
    • Say#word
  • クラスメソッド
    • Say.word
      • もしくは
    • Say::word

クラスメソッドを定義する(その2)class << self

  • 基本のクラスメソッドの定義方法
    • def self.メソッド名
  • 複数のクラスメソッドをまとめて書く場合は下記の記法が便利
    • class << self
class クラス名
  class << self
    def メソッド名
    end
  end
end
class Say
  class << self
    def word(text)
      text
    end
  end
end

p Say.word("Hi")
# "Hi"
  • ほかにも def self.メソッド名def クラス名.メソッド名 という記法もあるが
    • これはクラス名が変わった際に、メソッド名も変更する必要が生じるため推奨されない
  • self は、クラス自身を指している
    • クラス名に変更があった場合でも影響を受けない

同じクラスのクラスメソッドを呼び出す

  • インスタンスメソッドと同じようにメソッド名だけを書けばよい
    • (レシーバを省略せずに書く場合)
      • self.クラスメソッド
        • もしくは
      • クラス.クラスメソッド
class Say
  def self.word
    "Hello"
  end
  def self.world
    "#{word} world"
  end
end

p Say.world
# "Hello world"

インスタンスメソッドからクラスメソッドを呼び出す

  • クラス.メソッド もしくは self.class.クラスメソッド と記述する
class Say
  def self.word # クラスメソッド
    "Hello"
  end
  def world # インスタンスメソッド
    "#{Say.word} world"
  end
end

say = Say.new
p say.world
"Hello world"
  • クラスメソッドからインスタンスメソッドは呼び出せない
    • クラスからは、レシーバとなるインスタンスを決めることができないため