12

这是一个更普遍的问题,然后是特定于语言的问题,尽管我在玩 python ncurses 模块时遇到了这个问题。我需要显示语言环境字符并将它们识别为字符,所以我只是快速地从 curses 模块中修补了一些函数/方法。

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

不过,在我看来,更普遍的问题是——显然有些语言允许我们在类中对大块代码进行猴子补丁。如果这是我自己用的代码,或者改动很小,没关系。如果其他开发人员使用我的代码怎么办,他看到我使用了一些众所周知的模块,所以他可以假设它像以前一样工作。然后,这种方法突然表现得与它应该的不同。

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


编辑:对于@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/")
4

4 回答 4

9

不!

尤其是对于免费软件,您有所有可能将您的更改纳入主发行版。但是,如果您在本地副本中存在薄弱的黑客攻击,您将永远无法发布该产品,并且升级到下一个版本的 curses(任何人都可以进行安全更新)的成本将非常高。

请参阅此答案以了解外国代码库的可能性。链接的截屏视频真的值得一看。突然间,一个肮脏的黑客变成了有价值的贡献。

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

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

于 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 question进行讨论),这与 Python 的稍微少一点的 OO 实现有关。所以我会很谨慎,并倾向于在猴子修补之前花一些精力寻找替代品。

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

于 2009-01-06T09:04:32.040 回答