Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

ActiveSupport | Module#alias_method_chain (公式サイトに載っていないブロック呼び出しのサンプル付)

概要

Module#alias_method_chain

詳細

Module#alias_method_chainについて

Module#alias_method_chain

メソッドエイリアスを付与する際に、old_with_new,old_without_new
という名称のエイリアスを生成する。(メソッド名の衝突防止)
※old=古いメソッド名,new新しいメソッド

ブロック呼び出し

ブロックを指定することが可能で、引数としてメソッド名と句読(!や?)を取得できます。
ブロックに関しては公式ドキュメントの記載がないため、RailsGitHubリポジトリ内を
散策してで利用箇所を探してみました。

下記のファイルに利用箇所があります。
https://github.com/rails/rails/blob/e20dd73df42d63b206d221e2258cc6dc7b1e6068/activesupport/lib/active_support/deprecation/method_wrappers.rb

deprecateの設定に利用されている。
deprecate対象として指定されたメソッド名のリストを利用して、
動的にalias_method_chainのfeatureにあたるメソッドを定義するために利用しているようです。

サンプル

# encoding: utf-8
require 'active_support/core_ext/module/aliasing'
require 'test_toolbox'

class Hoge
  def hoge
    "hoge"
  end

  def hoge_with_hige
    hoge_without_hige + "hige"
  end

  alias_method_chain :hoge, :hige
end

p Hoge.new.hoge
p Hoge.new.hoge_with_hige
p Hoge.new.hoge_without_hige

class Hage
  def hage!
    "hage"
  end

  [
    {
      method_name: :cho_hage,
      value: :'cho'
    },
    {
      method_name: :ultra_hage,
      value: :'ultra'
    }
  ].each do |each_hage|
    alias_method_chain :hage!, each_hage[:method_name] do |aliased_target, punctuation|
      method_name = each_hage[:method_name].to_s
      define_method "#{aliased_target}_with_#{method_name}#{punctuation}" do
        orign = send :"#{aliased_target}_without_#{method_name}#{punctuation}"
        "#{each_hage[:value]}-#{orign}"
      end
    end
  end
end

dp_line __LINE__
p Hage.new.hage!
p Hage.new.hage_with_cho_hage!
p Hage.new.hage_without_cho_hage!
p Hage.new.hage_with_ultra_hage!
p Hage.new.hage_without_ultra_hage!

__END__
・下記はTbpgrUtils gemの機能
dp_line

https://rubygems.org/gems/tbpgr_utils
https://github.com/tbpgr/tbpgr_utils

・サンプル中のhage!系のメソッドは本来の命名だと破壊的ではないのでエクスクラメーションマークをつけない
のが正しいですが、punctuation部の動作確認のためにあえてエクスクラメーションマークを含んだ命名にしています。

出力

"hogehige"
"hogehige"
"hoge"
--------------------|filename=|line=46|--------------------
"ultra-cho-hage"
"cho-hage"
"hage"
"ultra-cho-hage"
"cho-hage"