12

これはより一般的な質問であり、言語固有のものですが、python ncurses モジュールで遊んでいるときにこの問題に遭遇しました。ロケール文字を表示し、それらを文字として認識させる必要があったため、curses モジュールのいくつかの関数/メソッドにモンキー パッチを適用しました。

これは、機能するとしても、高速で醜いソリューションと私が呼ぶものでした。そして、変更は比較的小さかったので、何も台無しにしていないことを願っています. 私の計画は別の解決策を見つけることでしたが、それが機能し、うまく機能しているのを見て、対処しなければならなかった他の問題に進みました。これにバグがなければ、決して解決しません改善する。

しかし、より一般的な質問が私に現れました-明らかに、一部の言語では、クラス内のコードの大きなチャンクをモンキーパッチすることができます。これが自分だけのコードであるか、変更が小さい場合は問題ありません。ただし、他の開発者が私のコードを使用した場合、彼は私がよく知られたモジュールを使用していることを知っているので、以前と同じように機能すると想定できます。次に、このメソッドは突然、本来の動作とは異なる動作をします。

では、非常に主観的な話ですが、モンキー パッチを使用する必要がありますか。どのように文書化する必要がありますか?


編集:@ゲルダのために:

モンキー パッチは、コード自体を変更することなく、実行時にコードの一部の動作を動的に変更する機能です。

Python での小さな例:

import os
def ld(name):
    print("The directory won't be listed here, it's a feature!")

os.listdir = ld

# now what happens if we call os.listdir("/home/")?
os.listdir("/home/")
4

4 に答える 4

9

しないでください!

特にフリー ソフトウェアの場合、変更をメイン ディストリビューションに含める可能性はすべてあります。しかし、ローカル コピーに脆弱な文書化されたハックがある場合、製品を出荷することはできず、curses の次のバージョンへのアップグレード (セキュリティ アップデートは誰でも) は非常に高額になります。

外部コードベースで何が可能かを垣間見るには、この回答を参照してください。リンクされたスクリーンキャストは一見の価値があります。突然、汚いハックが貴重な貢献に変わります。

なんらかの理由でアップストリームにパッチを取得できない場合は、少なくともローカル (git) リポジトリを作成してアップストリームを追跡し、別のブランチに変更を加えてください。

最近、最後の手段としてモンキー パッチを受け入れなければならない状況に遭遇しました。Puppet「どこでも実行できる」Ruby コードです。エージェントは (認定されている可能性がある) システムで実行する必要があるため、特定の ruby​​ バージョンを要求することはできません。それらのいくつかには、ランタイムで select メソッドにモンキー パッチを適用することで回避できるバグがあります。これらのパッチはバージョン固有であり、含まれており、ターゲットは凍結されています。他に選択肢はありません。

于 2009-01-06T09:05:02.930 に答える
4

しないでください。

各モンキー パッチは例外であり、追跡しやすいように (たとえば //HACK コメントで) マークする必要があります。

誰もが知っているように、醜いコードをそのままにしておくのは簡単です。なぜなら、それが機能するからです。したがって、醜いコードは長い間存在します。

于 2009-01-06T08:21:38.913 に答える
3

実稼働コードにモンキー パッチを適用することは、通常は良い考えではないという点で、私はDavidに同意します。

ただし、それをサポートする言語では、モンキー パッチは単体テストにとって非常に価値のあるツールであると私は信じています。複雑な依存関係がある場合でも、テストする必要があるコードの一部を分離できます。たとえば、依存関係を注入できないシステム コールがあります。

于 2011-02-07T13:43:28.447 に答える
0

この質問は、単一の決定的な「はい」「いいえ」/「良い」「悪い」という答えでは解決できないと思います。言語とその実装の違いを考慮する必要があります。

Python では、クラスにモンキー パッチを適用できるかどうかを検討する必要があります (ディスカッションについては、このSO の質問を参照してください)。これは、Python のわずかにオブジェクト指向が少ない実装に関連しています。そのため、私は用心深く、モンキー パッチを適用する前に代替手段を探す努力をする傾向があります。

インタープリターにオブジェクト指向で組み込まれた OTOH の Ruby では、C で実装されているか Ruby で実装されているかに関係なく、クラスを変更できます。オブジェクト (ほぼすべての基本クラス) でさえ、変更することができます。そのため、そのコミュニティでは、モンキー パッチが技術として積極的に採用されています。

于 2009-01-06T09:04:32.040 に答える