如何在Ruby中进行安全的、向后兼容的“反Monkeypatch”操作?

4
如果你的同事在Ruby中“打开”(“monkeypatch”)一个类并重新定义了一些你需要使用的重要功能,那么你如何访问那个原始的、未经过猴子补丁处理的功能,而不会破坏已经依赖于他的猴子补丁定义的系统?

1
你能提供一些更多的上下文信息吗?这是哪种类型的猴子补丁?(重新定义单个方法?多个方法?还是其他什么?) - Greg Campbell
1
比如说,他重新定义了 Ruby 内置的 Numeric 类中的 + 方法,使其执行减法而不是加法,现在我需要在应用程序中执行加法 - 我该如何访问 Numeric 类中 + 方法的原始功能? - pez_dispenser
1
如果你也遇到了这种问题,问一下 monkey patching 是否是一个好的解决方案可能是值得的 - 或许一个明确的类或模块会是更好的途径。 - paulthenerd
3个回答

5

以方法重写为例,如果你能在他的猴子补丁加载之前加载一些代码,那么你可以给该方法取一个别名。

class Fixnum
  alias_method :original_plus, :+
end

class Fixnum
  def +(x)
    self - x
  end
end

>> 5 + 3
=> 2
>> 5.original_plus(3)
=> 8

1
如果你有源代码的访问权限,你可以直接将你的代码放在同一个文件中,放置于你的同事的monkeypatch之前。否则,答案将取决于你的程序如何被加载。 - Ian Terrell
这是我能想到的最接近解决方案,但我不确定如何影响代码加载的顺序。我该如何坚持在猴子补丁之前加载别名 - 只需像您在此处所做的那样吗?也就是说,在源代码中插入先前点的定义 - 这真的是所有需要的吗? - pez_dispenser
假设你也可以访问他代码库的这一部分,只需将别名文字直接粘贴在他的 monkeypatch 上方。 - Chuck
除了 REST 场景外,在 Ruby 合作情况下,您总是可以访问源代码的,对吗? - pez_dispenser

3

我最近在RubyFlow上看到了这个简单的库,它可以让你命名空间顶级常量,叫做aikidoka。如果没有说明如何和什么被monkey patched,那么帮助就有点困难了。理论上,您可以使用这样的方法来对类的monkey-patched版本进行命名空间,以便您可以独立地访问它和原始版本。


这不需要您重构代码库,以使用新名称 Twitter::Mash 替代 Mash 吗? - pez_dispenser
即使在上面回答的alias_method情况下,由于您正在以两种不同的方式定义相同的功能,几乎肯定需要使用不同的名称引用其中一个版本。 - paulthenerd

0

具体取决于更改了哪些功能以及以何种方式更改,但是实现类似Jim Wienrich的BlankSlate类的东西可能会有所帮助:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接