今日はモンキーパッチの話をします。端的に言えば、言語の組み込みクラスやライブラリ、その他外部ライブラリの挙動を、動的に拡張する仕組みをモンキーパッチと呼びます。モンキーパッチのすごく単純な例として以下のようなものがあります。返すようになりますさて、このようなパッチが読み込まれたシステムでは、予想外の挙動が起きます。メソッドを受け取れないはずが、パッチが存在するためにフォールバックせず、挙動が変わってしまいます。メソッドを追加するモンキーパッチは、あとで述べるように、モンキーパッチとしては行儀の悪い部類です。このパッチは、実はかつて実際にクックパッドに存在していたものです。クックパッドの中心となるアプリケーションのレポジトリは最初に作られてから10年弱が経過しており、歴史的経緯から様々なモンキーパッチが存在します。われわれは、これらのモンキーパッチとうまくやる方法を考えていく必要があります。アプリケーションにおける、モンキーパッチの当て方、そして、モンキーパッチの外し方について紹介します。アプリケーションを書いていて、ライブラリなどの標準の挙動を変えるためにモンキーパッチを導入したいと考えたとします。その際、まずは最初の原則を当てはめましょう。モンキーパッチを使わないまず、本当にモンキーパッチを当てる必要があるかを考えましょう。それが何らかの不具合に対する対策だとしたら、ライブラリを最新バージョンにアップデートすることで対応できませんか。発想がモンキーパッチになってはいけません。何らかの組み込みクラスの挙動を変えたい場合、クラスそのものを拡張する以外の方法は取れないか考慮するべきです。いうほぼ同等の代替手段があるので回避できるはずでした。いう観点ではこのモンキーパッチは入れるべきものではなかったと言えます。それでもモンキーパッチを当てたいときとは言え、モンキーパッチを使わざるを得ない場面が起きるかも知れません。ある例として、外部のライブラリになんらかのバグがあるがそれが修正されたバージョンがリリースされていない場合、または、ライブラリのアップデートによる影響範囲が大きく別途検証が必要なためにすぐにアップデートできない場合などです。以上のような理由でモンキーパッチを当てなければならない場合、最大限パッチをコントロールする必要があります。パッチを隔離するモンキーパッチを導入することを決めたとき、まず行なうべきはモンキーパッチ用のディレクトリを作成することです。これによって、他のモジュールやクラスに影響を与えるコードを一箇所に集めることで一覧性を高め、読み込みのタイミングを統一します。変更させるべきではないうものがあります。ライブラリにパッチを当てたとしても、新しいインターフェースを増やしたり、既存のインターフェースを変更させないということです。これによって、モンキーパッチを外すときの労力がかなり下がります。追加するというパッチは、この原則に則しておらず、実際にパッチを除去する際に大きな労力を要しました。パッチが不要になったときに外せるようにするさて、影響範囲を最小限にするという観点では、パッチが不要になるタイミングで適切にキャッチアップしてパッチを削除することができるようになるべきです。最低限やるべきは、なぜそのパッチを導入することになったかをコメントとして残すことです。いう状態になればパッチを外して良いかまで明記されていると、将来の自分やチームメンバーがそのパッチを外せるかどうかで悩むことを防げます。良い方法は、パッチが不要になったら開発者が自動的に気づけるようにすることです。ライブラリの特定のバージョンの挙動に依存してパッチを当てざるを得なくなった場合、以下のようにライブラリをアップデートしたら例外が発生するようにして、もしパッチを消し忘れてもテスト実行時などに気づけるようにします。here...endNanika.prepend(NanikaMonkeyPatch)このように、大規模なアプリケーションにモンキーパッチを当てる際には細心の配慮をもって対応する必要があります。モンキーパッチの外し方さて、当てたモンキーパッチはいずれは外されなければなりません。次に、どのようにモンキーパッチを外すのかについて論じていきます。モンキーパッチを当てるときに注意を払えば、開発者はどのタイミングで外せるかを気づくことができるし、安全に外せるようになっているはずです。モンキーパッチを外す作業は、外部ライブラリのアップデートや内部ライブラリの挙動を変更した場合の対応とほぼ同じです。影響範囲を調べて、動作確認をして、問題なければリリースするという手順を踏みます。先述の通り、ライブラリのインターフェースはパッチを当てた場合も外した場合も同じであることが期待されるので、基本的にアプリケーションのコードを変更する必要はないはずです。実際はパッチによる副作用によって思わぬ場所で不具合が発生するかも知れないので、一度入れたパッチは細心の注意を払って外すべきです。アプリケーションにおけるモンキーパッチの当て方について記述しました。使うことがアプリケーションの寿命を延ばす秘訣であると考えます。インタプリタを開発している笹田です。今年のクリスマスに...2017-12-19料理教室のデザインリニューアルを支えた技術デザインの全面リニューアルという大規模な変更をスムーズに行...2016-03-29安心してRailsアップグレードを行うための工夫こんにちは。自分で作り始め...2015-06-22シンプルで移行しやすいデータベースシャーディング技術部の小野(taiki45)です。使ったセキュリティログ検索基盤の構築サービス特性にあった検索システムの設計戦略クックパッド採用説明会「クックパッドはサービスの作り手を採用したいんです。/*}*/スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。