Rubyのクラスメソッドとインスタンスメソッド 仕組みとベストプラクティス

Rubyのクラスメソッドとインスタンスメソッド 仕組みとベストプラクティス

Rubyでは、クラスメソッドとインスタンスメソッドを使い分けることで、柔軟な設計が可能になります。それぞれの役割と仕組みを理解し、適切に活用するためのベストプラクティスを学びます。

クラスメソッドとインスタンスメソッドの違い

クラスメソッドはクラスそのものに対して定義され、インスタンスメソッドはクラスのインスタンスに対して定義されます。

class Example
  def self.class_method
    "This is a class method"
  end

  def instance_method
    "This is an instance method"
  end
end

puts Example.class_method        # => "This is a class method"
puts Example.new.instance_method # => "This is an instance method"

クラスメソッドの定義方法

クラスメソッドはselfを使うか、特異クラス(クラスのメタクラス)に直接定義します。

class Example
  # selfを使った定義
  def self.method_one
    "Class method one"
  end

  # 特異クラスに直接定義
  class << self
    def method_two
      "Class method two"
    end
  end
end

puts Example.method_one # => "Class method one"
puts Example.method_two # => "Class method two"

インスタンスメソッドの定義方法

インスタンスメソッドは、クラス内でdefを使用して定義します。

class Example
  def greet(name)
    "Hello, #{name}!"
  end
end

example = Example.new
puts example.greet("Ruby") # => "Hello, Ruby!"

クラスメソッドの用途

クラスメソッドは、クラス全体で共有されるロジックや、インスタンス化する必要のない処理に適しています。

class MathUtility
  def self.square(number)
    number ** 2
  end
end

puts MathUtility.square(4) # => 16

インスタンスメソッドの用途

インスタンスメソッドは、インスタンス固有のデータや状態を操作するために使用します。

class Person
  def initialize(name)
    @name = name
  end

  def greet
    "Hi, I'm #{@name}"
  end
end

person = Person.new("Alice")
puts person.greet # => "Hi, I'm Alice"

クラス変数とインスタンス変数

クラス変数(@@)はクラス全体で共有され、インスタンス変数(@)はインスタンス固有です。

class Counter
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.total_count
    @@count
  end
end

Counter.new
Counter.new
puts Counter.total_count # => 2

クラスインスタンス変数の利用

クラスインスタンス変数は、特定のクラスにのみ関連付けられるデータを管理します。

class Configuration
  @setting = "default"

  def self.setting
    @setting
  end

  def self.setting=(value)
    @setting = value
  end
end

puts Configuration.setting # => "default"
Configuration.setting = "custom"
puts Configuration.setting # => "custom"

クラスメソッドとインスタンスメソッドの組み合わせ

クラスメソッドを使ってインスタンスを生成するファクトリメソッドを定義するのが一般的です。

class Person
  def self.create_with_name(name)
    new(name)
  end

  def initialize(name)
    @name = name
  end

  def greet
    "Hello, #{@name}"
  end
end

person = Person.create_with_name("Bob")
puts person.greet # => "Hello, Bob"

selfキーワードの役割

selfは、現在のコンテキストでの「自分自身」を表します。クラス内のselfはクラスそのものを指します。

class Example
  def self.show_self
    self
  end
end

puts Example.show_self # => Example

ベストプラクティス:明確な責任分担

クラスメソッドをデータの共有やユーティリティに、インスタンスメソッドを状態管理に使い分けることで、コードの保守性を高めます。

ベストプラクティス:DRY原則の遵守

共通のロジックをクラスメソッドに移動させることで、重複を避けることができます。

class StringUtility
  def self.capitalize_words(string)
    string.split.map(&:capitalize).join(" ")
  end
end

puts StringUtility.capitalize_words("hello world") # => "Hello World"

まとめ

クラスメソッドとインスタンスメソッドを適切に使い分けることで、Rubyのコードはよりシンプルで強力になります。両者の役割と仕組みを理解し、適切に設計しましょう。