モンキーパッチ
モンキーパッチは、オリジナルのソースコードを変更することなく、実行時に動的言語(例えばSmalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, など)のコードを拡張したり、変更したりする方法である。
このプロセスは"ダックパンチング"としても説明されてきた。[1]
目次 |
語源 [編集]
当初はモンキーパッチは、ルールを無視して実行時にこっそりとコードを変更することから、ゲリラパッチと呼ばれていた。これらのパッチを複数当てると、時折直感に反するような相互作用が生まれることがあり、Zope 2では、交戦中のパッチと呼ばれていた。
ゲリラとゴリラは同音異字に近かったため、何人かの人がゲリラパッチの代わりにゴリラパッチという間違った用語を使用し始めた。交戦することのないゲリラパッチを開発者が作成するのが非常に難しかったため、より弱そうに聞こえるモンキーパッチという用語が作られることになった。[2]
モンキーパッチという用語はそれ以来使用され続けているが、それを使用するコミュニティによって用語の定義は異なる。
Pythonではモンキーパッチという用語は、バグや思い通りに動かない機能の修正のために、外部のクラスにある既存のメソッドに対し、パッチを当てることで実行時のクラスを動的に変更する場合にだけ使用する。[要出典] 他の形式の、実行時のクラスの変更には、他の名前が付いている。例えば、ZopeとPloneでは、セキュリティパッチは動的なクラスの変更によって提供されるが、これらはホットフィックスと呼ばれる。
Rubyでは、モンキーパッチという用語は、あらゆるクラスに対する動的な変更のことを意味し、実行時の動的なクラスの変更と同義語になっている。[要出典]
Ruby界のメンバーの中には、モンキーパッチングの代わりにダックパンチングという用語を使い始めた人もいる。この用語は、Adam Keysとpatrick EwingがRailsConf 2007で説明した用語で、RubyとPythonではダックタイピングが大規模に使用してされていることから来ている: [3]
さて、私はAdamに買われてしまいましたが、その考えというのは、それがアヒルのように歩き、アヒルのように話すのであれば、それはアヒルということですよね?もしもこのアヒルが、あなたの望むような鳴き声をあげていないのであれば、期待しているものを返してくるまで、そのアヒルをパンチし続けなければなりません。
— Patrick Ewing
応用例 [編集]
モンキーパッチは以下の用途で使用される。
- メソッド/属性/関数を実行時に置き換えることで、テストの間は使用される関数をスタブに変更して、何もアウトプットしないようにする。
- ソースコードの私的なコピーをメンテナンスし続けることなく、サードパーティ製のプログラムの振る舞いを変更したり、拡張したりする。
- ディスク上のソースコードを書き換えることなく、実行時に、メモリ中のオブジェクトに対してパッチを適用する。
- オリジナルのソースコードと並存するようなセキュリティフィックス及び、動作のフィックスの配布。Ruby on Railsプラットフォーム用のプラグインとして配布されている修正パッチがこれの例になる。
落とし穴 [編集]
丁寧に作られていなかったり、ドキュメントが貧弱だったりするモンキーパッチからは、以下のような問題が引き起こされることがある:
- 状況が変わり、そのパッチが、変更される対象のオブジェクトに対して仮定していることがもう正しくなくなってしまった場合に、アップグレードにまつわる問題が引きおこされる。もしもパッチを適用したプロダクトが新バージョンになって変更されると、パッチが壊れて動作しなくなる可能性が高い。このような理由からほとんどの場合において、モンキーパッチは、条件をチェックして、適切な時だけ適用するように作られる。
- もしも、同じメソッドに対して、2つのモジュールが同時にモンキーパッチを適用しようとすると、それが
alias_method_chainのようなパターンを使用して書かれていない限りは後から実行した方が"勝ち"、もう片方のパッチは動作しない[4]。 - モンキーパッチを適用すると、ディスク上の元のソースコードと、見た目の振る舞いが異なるため、パッチの存在に気づかなかった人を混乱させる可能性がある。
例え使用されていなかったとしても、プログラミング言語内でモンキーパッチを適用できるということは、強いカプセル化を強制することと両立しないため、モンキーパッチの機能の有用性は問題である、と見る人も中にはいる。このオブジェクト間のカプセル化は、Object-capability_modelで必要とされる。
参考 [編集]
- ^ Delabar, Eric (2008年5月2日). “Duck Punching JavaScript - Metaprogramming with Prototype”. 2008年7月3日閲覧。
- ^ Limi, Alexander; Shane Hathaway (2005年12月23日). “Monkey patch”. Plone Foundation. 2008年7月3日閲覧。
- ^ Grosenbach, Geoffrey (2007年5月21日). “RailsConf 2007”. 2008年7月3日閲覧。
- ^ “New in Rails: Module#alias_method_chain” (2006年4月26日). 2010年1月26日閲覧。