猴子补丁还是不?

发布于 2024-07-11 01:11:16 字数 780 浏览 8 评论 0原文

这是比特定于语言更普遍的问题,尽管我在使用 python ncurses 模块时遇到了这个问题。 我需要显示区域设置字符并将它们识别为字符,因此我只是快速修补了 curses 模块中的一些函数/方法。

这就是我所说的快速而丑陋的解决方案,即使它有效。 而且变化相对较小,所以我希望我没有搞砸任何事情。 我的计划是找到另一个解决方案,但是看到它有效并且运行良好,你知道它是怎么回事,我继续处理我必须处理的其他问题,并且我确信如果这没有错误我永远不会让它变得更好。

不过,在我看来,更普遍的问题是——显然有些语言允许我们在类内对大块代码进行猴子修补。 如果这是我只为自己使用的代码,或者更改很小,那就可以了。 如果其他开发人员使用了我的代码,他看到我使用了一些众所周知的模块,那么他可以假设它按照习惯工作,该怎么办? 然后,这个方法突然表现得与应有的不同。

那么,非常主观的是,我们是否应该使用猴子补丁,如果是,何时以及如何使用? 我们应该如何记录它?


编辑:对于@guerda:

猴子修补是在执行时动态更改某些代码片段的行为而不改变代码本身的能力。

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/")

This is more general question then language-specific, altho I bumped into this problem while playing with python ncurses module. I needed to display locale characters and have them recognized as characters, so I just quickly monkey-patched few functions / methods from curses module.

This was what I call a fast and ugly solution, even if it works. And the changes were relativly small, so I can hope I haven't messed up anything. My plan was to find another solution, but seeing it works and works well, you know how it is, I went forward to other problems I had to deal with, and I'm sure if there's no bug in this I won't ever make it better.

The more general question appeared to me though - obviously some languages allow us to monkey-patch large chunks of code inside classes. If this is the code I only use for myself, or the change is small, it's ok. What if some other developer takes my code though, he sees that I use some well-known module, so he can assume it works as it's used to. Then, this method suddenly behaves diffrent then it should.

So, very subjective, should we use monkey patching, and if yes, when and how? How should we document it?


edit: for @guerda:

Monkey-patching is the ability to dynamicly change the behavior of some piece of code at the execution time, without altering the code itself.

A small example in 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/")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

农村范ル 2024-07-18 01:11:16

不!

特别是对于免费软件,您可以将更改添加到主发行版中。 但是,如果您的本地副本中存在记录薄弱的黑客行为,您将永远无法交付该产品,并且升级到下一个版本的curses(任何人的安全更新)将花费非常高的成本。

请参阅这个答案,让您一睹外国代码库的可能性。 链接的截屏< /a> 确实值得一看。 突然间,肮脏的黑客行为变成了有价值的贡献。

如果您确实因某种原因无法获得上游补丁,至少创建一个本地(git)存储库来跟踪上游并将您的更改放在单独的分支中。

最近我遇到了一个问题,我必须接受猴子修补作为最后的手段: Puppet 是一段“到处运行”的 ruby​​ 代码。 由于代理必须在(可能经过认证的)系统上运行,因此它不能需要特定的 ruby​​ 版本。 其中一些存在错误,可以通过在运行时对选择方法进行猴子修补来解决。 这些补丁是特定于版本的、包含的,并且目标被冻结。 我认为没有其他选择。

Don't!

Especially with free software, you have all the possibilities out there to get your changes into the main distribution. But if you have a weakly documented hack in your local copy you'll never be able to ship the product and upgrading to the next version of curses (security updates anyone) will be very high cost.

See this answer for a glimpse into what is possible on foreign code bases. The linked screencast is really worth a watch. Suddenly a dirty hack turns into a valuable contribution.

If you really cannot get the patch upstream for whatever reason, at least create a local (git) repo to track upstream and have your changes in a separate branch.

Recently I've come across a point where I have to accept monkey-patching as last resort: Puppet is a "run-everywhere" piece of ruby code. Since the agent has to run on - potentially certified - systems, it cannot require a specific ruby version. Some of those have bugs that can be worked around by monkey-patching select methods in the runtime. These patches are version-specific, contained, and the target is frozen. I see no other alternative there.

诠释孤独 2024-07-18 01:11:16

我想说不要。

每个猴子补丁都应该是一个例外并进行标记(例如使用 //HACK 注释),以便轻松追踪。

众所周知,将丑陋的代码保留在原处是很容易的,因为它可以工作,所以为什么要花更多的时间在它上面。 所以丑陋的代码将会存在很长一段时间。

I would say don't.

Each monkey patch should be an exception and marked (for example with a //HACK comment) as such so they are easy to track back.

As we all know, it is all to easy to leave the ugly code in place because it works, so why spend any more time on it. So the ugly code will be there for a long time.

七婞 2024-07-18 01:11:16

我同意 David 的观点,猴子修补生产代码通常是这不是一个好主意。

然而,我相信对于支持它的语言来说,猴子补丁是一个非常有价值的单元测试工具。 它允许您隔离需要测试的代码段,即使它具有复杂的依赖项 - 例如无法进行依赖项注入的系统调用。

I agree with David in that monkey patching production code is usually not a good idea.

However, I believe that for languages that support it, monkey patching is a very valuable tool for unit testing. It allows you to isolate the piece of code you need to test even when it has complex dependencies - for instance with system calls that cannot be Dependency Injected.

雪落纷纷 2024-07-18 01:11:16

我认为这个问题不能用一个明确的是-否/好-坏答案来解决——必须考虑语言及其实现之间的差异。

在 Python 中,需要考虑一个类是否可以进行猴子修补(请参阅此 SO 问题供讨论),这与 Python 的稍微不那么 OO 的实现有关。 因此,我会谨慎行事,并倾向于在进行猴子修补之前花费一些精力寻找替代方案。

在 Ruby 中,OTOH 是以 OO 方式构建到解释器中的,无论类是用 C 还是 Ruby 实现,都可以修改。 甚至 Object(几乎所有东西的基类)也可以修改。 因此,猴子补丁在该社区中作为一种技术被更热情地采用。

I think the question can't be addressed with a single definitive yes-no/good-bad answer - the differences between languages and their implementations have to be considered.

In Python, one needs to consider whether a class can be monkey-patched at all (see this SO question for discussion), which relates to Python's slightly less-OO implementation. So I'd be cautious and inclined to expend some effort looking for alternatives before monkey-patching.

In Ruby, OTOH, which was built to be OO down into the interpreter, classes can be modified irrespective of whether they're implemented in C or Ruby. Even Object (pretty much the base class of everything) is open to modification. So monkey-patching is rather more enthusiastically adopted as a technique in that community.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文