alias_method_chainとprependは共存するか

alias_method_chainは、Rails 5.0で非推奨に、Rails 5.1では使用不可(削除)となりました。

勤め先でもRailsのバージョンを4.x系から5.x系に上げることになり、alias_method_chainを使っている部分を順次prependで書き直すことになりました。

スポンサーリンク

alias_method_chainをprependに書き換える

一般的な書き直し方は次のようになるかと思われます。

#もととなるコード
#クラス定義
class TestClass
def test_method
print "This is #{self.class}"
end
end

#インスタンス化してメソッド呼び出し
test_class_instance = TestClass.new
test_class_instance.test_method

出力例)

This is TestClass
#alias_method_chainの場合
#クラス定義は前述のとおり
#alias_method_chain用モジュール
module TestModule
def test_method_with_hoge
test_method_without_hoge
print " and module"
end
end

#モジュールのインクルードとalias_method_chain
TestClass.class_eval do |klass|
include TestModule
alias_method_chain :test_method, :hoge
end

#インスタンス化してメソッド呼び出し
test_class_instance = TestClass.new
test_class_instance.test_method

出力例)

This is TestClass and module
#prependの場合
#クラス定義は前述のとおり
#prepend用モジュール
module TestModule
def test_method
super
print " and module"
end
end

#TestClassにprepend
TestClass.prepend(TestModule)

#インスタンス化してメソッド呼び出し
test_class_instance = TestClass.new
test_class_instance.test_method

出力例)

This is TestClass and module

alias_method_chainとprependは共存するか?

プロジェクトとして作業する場合は、全部一度に直すのではなく小さな単位に区切って修正していくと思います。

当方ではファイル単位に修正を進めていました。

しかし、同一のメソッドをalias_method_chainでモンキーパッチを当てている部分で、あるファイルではprependに直し、別ファイルはalias_method_chainのままにしておくと、メソッドの呼び出しで無限ループが発生してしまいました。

調べてみると、alias_method_chainとprependの順番によっては無限ループが発生するようです。

まとめ

alias_method_chainをprependに直す際は、同一メソッドに対して上書きしているものは、横展開して進めるのがよさそう。

コメント