2022-12-22 Rubyモンキーパッチ
Rubyモンキーパッチは、基本的にprepend
を使うのがよろし。
Module#prepend (Ruby 3.2 リファレンスマニュアル)
Gemにモンキーパッチを当てるサンプルよりコードを引用する。
インスタンスメソッドをパッチする
module SampleKlassMonkeyPatch def increment Rails.logger.warn 'DEPRECATION WARNING: 使わないで!' super end end
クラスメソッドをパッチする
module SampleKlassMonkeyPatch def increment(num) super(num.to_i) end end SampleGem::SampleKlass.singleton_class.prepend(SampleKlassMonkeyPatch)
ancestors
で継承ツリーを確認してprependされていることを確認できる。
# インスタンスメソッドの確認 # 自分のクラスより前にパッチが挿入されていたらOK > SampleGem::SampleKlass.ancestors => [SampleKlassMonkeyPatch, SampleGem::SampleKlass, ....] # クラスメソッドの確認 # 自分のクラスより前にパッチが挿入されていたらOK > SampleGem::SampleKlass.singleton_class.ancestors => [SampleKlassMonkeyPatch, #<Class:SampleGem::SampleKlass>, #<Class:Object>, ...]
パッチに賞味期限を付ける
パッチをあてるときのグッドプラクティスとして賞味期限を設けるのが良い。
# lib/monkey_patches/nanika_ext.rb require 'nanika/version' unless Nanika::VERSION == "2.2.0" raise "Consider removing this patch" end module NanikaMonkeyPatch # monkey patches go here... end Nanika.prepend(NanikaMonkeyPatch)