define_method
インスタンスメソッドを定義します。
Ruby 3.1 リファレンスマニュアル
動的にメソッドを作れる。
特徴
Gomiテーブルでゴミの種類を判別するメソッドがあるとする。判別にはkindカラムを使っている。
静的にメソッドを定義している状態。これだとプラごみとか缶・ビンのゴミを追加するたびにメソッドも増やす必要が出てくる。
class Gomi
attr_accessor :kind
def recycle?
kind == "Recycle"
end
def burn?
kind == "Burn"
end
def raw?
kind == "Raw"
end
end
g = Gomi.new
g.kind = "Burn"
g.raw? #=> false
g.burn? #=> true
define_methodを使って動的にメソッドを定義したコード。今後ゴミの種類が増えたとしてもメソッドは1つで足りる。
class Gomi
attr_accessor :kind
KIND = ["Recycle", "Burn", "Raw"]
KIND.each do |k|
define_method(:"#{k.downcase}?") { kind == k }
end
end
g = Gomi.new
g.kind = "Burn"
g.raw? #=> false
g.burn? #=> true
define_singleton_methodとは
self に特異メソッドを定義します
Ruby 3.1マニュアルリファレンス
特異メソッドを定義できる。
特徴
ゴミの種類ごとに最新のレコードを取得する処理があるとする。
class Gomi
attr_accessor :kind
KIND = ["Recycle", "Burn", "Raw"]
def self.latest_recycle?
where(kind: recycle).last
end
def self.latest_burn?
where(kind: burn).last
end
def self.latest_raw?
where(kind: raw).last
end
end
define_singleton_methodを使って特異メソッドを設定する。
class Gomi
attr_accessor :kind
KIND = ["Recycle", "Burn", "Raw"]
KIND.each do |k|
define_singleton_method(:"latest_#{k.downcase}") { where(kind: k).last }
end
end
まとめ
define_methodはインスタンスメソッドを動的に作れる。同じ処理をしているメソッドがあれば使えるかもしれない。
define_singleton_methodは特異メソッドを動的に作れる。こちらも同じ処理を繰り返して使っている場合は使えるかもしれない。