猴子补丁还是不补?

时间:2009-01-06 07:58:21

标签: oop language-agnostic monkeypatching

这是更普遍的问题,然后是语言特定的,虽然我在使用python ncurses模块时碰到了这个问题。我需要显示区域设置字符并将它们识别为字符,所以我很快就从curses模块中修补了一些函数/方法。

这就是我称之为快速而丑陋的解决方案,即使它有效。而且变化相对较小,所以我希望我没有搞砸任何东西。我的计划是找到另一个解决方案,但看到它的工作和运作良好,你知道它是怎么回事,我继续处理我必须处理的其他问题,我敢肯定,如果没有这个问题,我将永远不会让它变得更好。

虽然看起来更普遍的问题 - 显然有些语言允许我们在类中修补大块代码。如果这是我自己只使用的代码,或者变化很小,那就没关系。如果其他开发人员接受我的代码会怎样,他看到我使用了一些众所周知的模块,所以他可以认为它可以像以前一样工作。然后,这种方法突然表现得与之不同。

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


编辑:for @guerda:

Monkey-patching是在执行时动态改变某段代码行为的能力,而不会改变代码本身。

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

5 个答案:

答案 0 :(得分:8)

不要!

特别是使用免费软件,您可以获得所有可能性,以便将更改纳入主要发行版。但是,如果你在本地副本中有一个文档记录较少的黑客,你将永远无法发布产品并升级到下一版本的curses(安全更新任何人)将是非常高的成本。

请参阅this answer,了解外国代码库的可能性。 linked screencast非常值得关注。突然间,一个肮脏的黑客变成了一个有价值的贡献。

如果由于某种原因你真的无法上传补丁,至少要创建一个本地(git)仓库来跟踪上游并在单独的分支中进行更改。

最近我遇到了一个问题,我必须接受猴子修补作为最后的手段:Puppet是一个“无处不在”的红宝石代码。由于代理必须运行 - 可能已经认证 - 系统,因此不需要特定的ruby版本。其中一些有bug可以通过运行时中的猴子修补select方法来解决。这些修补程序是特定于版本的,包含的,并且目标被冻结。我认为没有其他选择。

答案 1 :(得分:4)

我会说不要。

每个猴子补丁应该是一个例外并标记(例如使用// HACK注释),因此它们很容易追溯。

众所周知,将丑陋的代码留在原处是很容易的,因为它有效,所以为什么要花更多的时间在它上面呢。所以丑陋的代码将存在很长时间。

答案 2 :(得分:3)

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

但是,我相信对于支持它的语言,猴子修补是一个非常有价值的单元测试工具。它允许您隔离需要测试的代码片段,即使它具有复杂的依赖关系 - 例如,系统调用不能是依赖注入的。

答案 3 :(得分:0)

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

在Python中,需要考虑是否可以对一个类进行猴子修补(请参阅此SO question以进行讨论),这与Python的OO实现略少。所以我要小心谨慎,倾向于在猴子补丁之前花一些力气寻找替代方案。

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

答案 4 :(得分:-1)

一个词:oscommerce。

如果你在玩弄

之前从未玩过它
// BOF: Fixed/added/removed bla bla bla
...
// EOF

更不用说由于“将功能放在任何地方”的心态,整个代码库已经降级。更新的编程概念,如OO(继承和复合类),旨在使这些非问题。使用它们!