[Rails]alias_method_chain

alias_method_chainはRails5.0で非推奨、Rails5.1で使用不可になったメソッド。

使用用途

以下のコードのhelloでputsする内容にタイムスタンプを含めたい。

が、呼び出し側で考慮して、 `hello(“#{Time.now} メッセージ”)と出力したくない

module Greeting
  def hello(message)
    puts message 
  end
end
include Greeting
hello('Hello')

これを実現するためにはalias_methodで置き換える

module Greeting
  def hello(message)
    puts message
  end
  
  def hello_with_timestamp(message)
    hello_without_timestamp("[#{Time.now}]#{message}")
  end
  
  # hello_without_timestampで既存のhelloの実装を置き換えている
  alias_method :hello_without_timestamp, :hello
  
  # helloはhello_with_time_stampを参照する
  alias_method :hello, :hello_with_timestamp
end

# ↓で動作確認
include Greeting
hello("hello")

これを alias_method_chain を使えばもっと簡潔に書くことができる。 新しいメソッドはxxx_with_xxxという名前、旧メソッドはxxx_without_xxxという名前に置き換えられる。

# alias_method_chainはもう使用不可になっているのでこのコードは動かない
module Greeting
  def hello(message)
    puts message
  end
  
  def hello_with_timestamp(message)
    hello_without_timestamp("[#{Time.now}]#{message}")
  end

  alias_method_chain :hello, :timestamp
end

Module.prependが代替手段に

Module.prependを使えばalias_method_chainを使わなくても同じことができる

class Greeting
  def hello
    "hello"
  end
end
module TimeStampGreeting
  def hello
    "[#{Time.now}]" + super
  end
end

class Greeting
  prepend TimeStampGreeting
end

puts Greeting.new.hello
# => [2023-01-27 22:02:45 +0900]hello

【参考】