Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Smalltalk如何处理monkeypatching?_Ruby_Smalltalk_Monkeypatching - Fatal编程技术网

Ruby Smalltalk如何处理monkeypatching?

Ruby Smalltalk如何处理monkeypatching?,ruby,smalltalk,monkeypatching,Ruby,Smalltalk,Monkeypatching,我是一名Ruby程序员。对我来说,monkeypatching就是在运行时更改外部项目中的类或模块方法。我感兴趣的是,你有什么机制可以保护你不受这个好功能的滥用。下面是我遇到的一些情况,monkeypatching咬了我一口 虽然我一点也不懂Smalltalk,但这种语言早在Ruby出现之前就已经存在了。我做了一些研究,看看Smalltalk是否以及如何解决了其中的一些问题,但在谷歌上没有找到多少。所以我在这里,询问那些小人是否可以分享他们的智慧 场景A:错误修复冲突 项目A和B依赖于项目C。项

我是一名Ruby程序员。对我来说,monkeypatching就是在运行时更改外部项目中的类或模块方法。我感兴趣的是,你有什么机制可以保护你不受这个好功能的滥用。下面是我遇到的一些情况,monkeypatching咬了我一口

虽然我一点也不懂Smalltalk,但这种语言早在Ruby出现之前就已经存在了。我做了一些研究,看看Smalltalk是否以及如何解决了其中的一些问题,但在谷歌上没有找到多少。所以我在这里,询问那些小人是否可以分享他们的智慧

场景A:错误修复冲突

项目A和B依赖于项目C。项目C有一个bug。项目A和B版本包含项目C的修复程序

如果您的代码使用项目A和B,您如何知道修补程序不会冲突

场景B:过时的错误修复

ProjectC发布其项目的固定次要版本

如果加载项目A,是否仍将应用修补程序,并可能导致损坏?我想知道是否有某种机制,例如,如果代码是固定的,就不加载补丁

场景C:冲突扩展

项目A和B使用项目C的Foo类。两者都为Foo添加了一个实用方法,比如#toDate。 A的toDate版本返回一个日期字符串,B的toDate版本返回一个日期对象

如果您同时加载两个项目(使用C dep),是否有一种机制可以警告/防止冲突?或者,您必须等到运行时因为方法中的错误预期而抛出错误时再执行吗

关于问题更新

在阅读答案时,我意识到我的问题过于宽泛和模糊。这是它的一个重写版本。

上面写着“是的!加油!”

整个概念很可能首先出现在Smalltalk中

转到类浏览器中的根类,可以将所有方法添加到所需的图像中


但是,请记住,Smalltalk与其他常用语言(唯一一种像Smalltalk一样常见的语言是APL)对世界的看法截然不同。您有一个包含整套代码和运行时包的映像。更改图像时,图像中的每一位代码都会受到影响。其他图像不会更改。您可以使用更改集来重新加载您最喜欢的黑客,但它们基本上是将代码导入到图像中。

Smalltalk用户不使用术语“monkey patching”,但我感觉“method overriding”是最接近的术语。也就是说,在包a中重写一个类的方法,在包B中重写同一类的方法。因此,当加载包B时,将重写包a中的原始方法


方法重写有其优点,但如果不小心使用,则有更多的缺点,因此通常我们倾向于避免它们。它还取决于Smalltalk方言——例如,在VisualWorks中,工具非常支持覆盖,而在Squeak中则不然。

在Smalltalk中,我们传统上称之为覆盖。根据Smalltalk使用的版本控制工具,您可以:

  • 创建最初拥有相关类/方法的包的新版本
  • 创建一个新包,该包将拥有相关类/方法的重写
在VisualWorks和ObjectStudio(我最熟悉的Smalltalk)中,使用了后一种方法。在使用嫉妒的VA Smalltalk中,采用了前一种方法。我相信Squeak会使用Monticello采用后一种方法,但我不能完全确定

在大多数Smalltalk实现中,很容易看到重写代码的原始版本和当前安装的重写

在客户端应用程序中,覆盖实际上只在您从venor(或Squeak团队等)更新到新版本的Smalltalk时才会对您产生影响。对于服务器应用程序,多个应用程序可能驻留在服务器中,您需要更加小心地决定要做什么


覆盖(或者你称之为monkey补丁)是一个强大的工具,但是你需要注意如何使用它们——如果你确实使用了它们,你应该定期重新检查你是否仍然需要它们。在我的开源新闻聚合器中,我删除了许多最初设置的覆盖

回答我自己,以下是我目前的观点:

场景A和场景B

因为所有代码都是开放的,所以最好的做法是直接修复损坏的项目。像git这样的工具已经在管理代码合并了,所以我们不需要依赖运行时mergin,这并不总是有效的

取决于上游是否愿意合并您的修复程序,以及发布新版本的速度,您可能会设想生成monkeypatch。在这种情况下,最好有一个机制,可以说:

monkeypatch(ClassName, :method, &newcode) of the broken project
is applied if project.version in [a set of releases where the bug exist]
if the project version is unknown to the monkeypatch,
  raise an error to tell the developer to fix the monkeypatch (check if bug exist).
if a monkeypatch for that project, classname and method already exist, yell
这是从我的头顶传来的。如果错误修复需要的不仅仅是方法更改,那么可能会出现问题


场景C:TODO

如果您正在寻找尖端解决方案,请查看转换框。转换盒的研究原型基于Squeak Smalltalk


请看

monkeypatch的功能真的是个问题吗?你对monkeypatch的批评似乎有点离题。monkeypatching中没有任何固有的东西会导致泄漏的抽象,就像在初始类设计中一样。它也不是天生比其他代码更“粗糙”。将一个对象拆分为不同的文件是正确的,尽管有些人会认为拥有可管理的模块是一件好事——事实上,在Objective-C中对相关功能进行分组被认为是一种良好的做法。也许你的问题更多的是编码人员而不是语言功能。在任何cae中,将事物分割成单独文件的整个概念是错误的;smalltalk不会这样做的。@C