比较来自世界各地的卖家的域名和 IT 服务价格

真的 "monkey patching" 真的这么糟糕?

某种语言如 Ruby 和 JavaScript, 有开放类,允许您更改甚至基本类的接口,例如数字,行,数组等显然,它可以混淆熟悉的其他人 API, 但是有没有充分的理由避免它,假设您添加到界面并不会更改现有行为?

例如,添加实现将很好 an Array.map 在不实现的Web浏览器中 ECMAScript 5th edition /如果你不需要一切 jQuery/. 或者你的阵列 Ruby 可以从一种方便的方法中受益 "sum", 哪种用途 "inject". 到目前为止,从系统中孤立的变化 /例如,不是您释放以分发的软件包的一部分/, 是否有有效的原因不使用此语言功能?
已邀请:

石油百科

赞同来自:

猴子修复,就像一组编程工具中的许多工具一样,可以用于良好和邪恶。 问题是,最终,这些工具最常使用。 在我的经验 Ruby 鳞片重量在侧面 "evil".

那么是什么 "evil" 使用拉丁猴? 嗯,拉伸猴子通常让你敞开敞开,潜在的非诊断碰撞。 我有一堂课
A

. 我有某种猴子校正模块
MB

, 哪个纠正
A

, 打开
method1

,
method2


method3

. 我有另一个猴子校正模块
MC

, 这也纠正
A

, 打开
method2

,
method3


method4

. 现在我处于绝望的位置。 我打电话
instance_of_A.method2

: 谁的方法被称为? 这个问题的答案可能取决于这些因素:

在哪个订单中,我输入了更正模块?

补丁是否立即适用或在某些条件情况下?

AAAAAAARGH! 蜘蛛从里面吃了我的眼睛!

OK, 以便 #3, 也许太丝身吻......

在任何情况下,这都是猴子拉巴尼亚的问题:可怕的冲突问题。 鉴于通常支持它的语言的高表达性质,您已经遇到了很多潜在问题。 "spooky action at a distance"; 猴子修复只会增加它们。

如果您是负责任的开发人员,可用猴子的存在很好。 很遗憾, IME, 通常,有人看到猴子补丁并说: "甜的! 我只是纠正它,而不是检查其他机制是否可以更合适。" 这是一种情况,大致类似于代码基础。 Lisp, 由伸展到的人创造 macros, 在考虑刚刚做到这一点之前。

莫问

赞同来自:

维基百科有猴子修正的水下石头摘要:

http://en.wikipedia.org/wiki/Monkey_patch#Pitfalls
石头

一切都有时间和地点,以及猴子拉巴尼亚。 经验丰富的开发人员在袖子中有很多技术,他们知道何时使用它们。 它很少发生在本身之上,哪个 "evil", 只是无所不在使用它。

奔跑吧少年

赞同来自:

到目前为止,这些变化是孤立的
你的系统 /例如,不部分值
您发布的软件包
分配/, 有没有充分的理由
不要使用这个语言
功能?

就像一个孤独问题的孤独开发人员一样,不扩展或更改自己的对象没有问题。 此外,在更大的项目中,这是应该完成的命令选择。

我个人不喜欢当地对象时 javascript 改变,但这是一个常见的做法,这是正确的选择。 如果您要编写用于其他人使用的库或代码,我将强烈避免它。

但是,这是设计的正确选择,允许用户设置配置标志,这使得您可以使用方便的方法覆盖自己的对象,因为它非常方便。

为了说明特定的陷阱 JavaScript.


Array.protoype.map = function map// { ... };

var a = [2];
for /var k in a/ {
console.log/a[k]/;
}
// 2, function map// { ... }


可以避免使用此问题 ES5, 这允许您输入对象引出的属性。

它基本上是一系列高级设计,每个人都应该知道 / 同意这一点。

知食

赞同来自:

使用是合理的 "monkey patching" 纠正特定的,众所周知的问题,其中替代方案是等待修补程序来解决它。 这意味着在正式发出纠正之前纠正某些事情的责任暂时采用。 "proper", 您可以部署哪些。

Gilad兄弟会关于拉美菊猴子的加权视图:
http://gbracha.blogspot.com/20 ... .html

莫问

赞同来自:

你描述的条件 - 添加 /不要换/ 没有现有的行为,而不是将代码发布到外部世界 - 看起来相对安全。 但是,如果以下版本可能会出现问题 Ruby, JavaScript 或者 Rails 改变它们 API. 例如,如果某种未来版本 jQuery 检查,它已经确定了 Array.map, 并假设这个版本 EMCA5Script map, 什么时候实际上是你的猴子补丁?

同样,如果您定义 "sum" 在 Ruby, 有一天,您可以决定要使用此代码的内容 ruby 在 Rails 或添加主动支持 gem 在你的项目中? 主动支持还定义了该方法 sum /on Enumerable/, 因此,出现碰撞。

奔跑吧少年

赞同来自:

关于 Javascript:

有没有充分的理由避免这种情况,假设您添加到界面并不会更改现有行为?

是的。 在最坏的情况下,即使你没有改变

现存的

你可以损坏的行为

未来

语言语法。

这就是发生的事情
https://github.com/tc39/proposal-flatMap/pull/56

https://bugzilla.mozilla.org/s ... 75059
. 简而言之,规范是为这些方法编写的。 , 他们的建议点击了
https://tc39.github.io/process-document/
, 然后浏览器开始发货。 但在这两种情况下都被发现了 , 什么存在于修复内置对象的古代图书馆
Array

用自己的方法

与新方法相同

, 并且具有不同的行为; 因此,网站已破坏,浏览器必须放弃其新方法的实现,并且应该已经编辑了规范。 /方法更名为。/

如果突破内置类型对象
Array


在自己的浏览器中,在您自己的计算机上

, 这是正常的。 /这是用户脚本的一个非常有用的技术。/ 如果在可公开的网站上突变内置对象,则不太正常 - 这是

能够

最终,导致与上述类似的问题。 如果你很幸运能够管理

大网站

/例如, stackoverflow.com/ 而且你改变了内置的对象,你几乎可以保证浏览器会拒绝引入新功能/违反您网站的方法 /因为那么这个浏览器的用户将无法使用您的网站,因此他们更有可能转到另一个浏览器/. /厘米。
https://coderoad.ru/55934490/
解释浏览器规范和制造商的作者之间的这种互动/

一切都被称为担心

具体例子

在您的问题中:

例如,添加实现将很好 an Array.map 在不实现的Web浏览器中 ECMAScript 5th edition

这是一种称为一个非常普遍和值得信赖的技术
https://en.wikipedia.org/wiki/ ... ming/
.

多百合 - 此代码实现不支持它的Web浏览器中的函数。 这通常是指图书馆 JavaScript, 它实现了Web标准 HTML5, 或建立标准 /由某些浏览器支持/ 在旧浏览器或拟议标准中 /没有浏览器/ 在现有浏览器中

例如,如果您为polyfill写了
Array.prototype.map

/或者如果你拿一个较新的例子
Array.prototype.flatMap

/, 哪一个

完全适合

https://tc39.github.io/ecma262 ... e.map
, 然后推出代码定义
Array.prototype.flatMap

在没有它的浏览器中:


if /!Array.prototype.flatMap/ {
Array.prototype.flatMap = function/...
// ...
}
}


如果您的实现为真,则完全正常,通常通过互联网进行,因此过时的浏览器可以了解新方法。
http://www.polyfill.io/
- 这是这种事情的常规服务。

要回复问题请先登录注册