【问题标题】:How can you do a safe, backwards-compatible "reverse-monkeypatch" in Ruby?你如何在 Ruby 中做一个安全的、向后兼容的“reverse-monkeypatch”?
【发布时间】:2009-05-16 02:41:50
【问题描述】:

如果您的同事在 Ruby 中“打开”(“monkeypatches”)一个类并重新定义了一些您需要使用的重要功能,您如何在不破坏已经依赖/依赖于他的猴子补丁定义?

【问题讨论】:

  • 您能否提供更多关于这是什么猴子补丁的背景信息? (重新定义一个方法?多个?别的?)
  • 比如说,他重新定义了 Ruby 内置 Numeric 类中的 + 方法来做减法而不是加法,现在我需要在应用程序中进行加法 - 我如何访问原始Numeric 类的 + 方法的功能?
  • 如果您也遇到此类问题,不妨问问猴子补丁是否是一个好的解决方案——也许显式的类或模块会是更好的方法。

标签: ruby reverse monkeypatching


【解决方案1】:

给定方法覆盖的例子,如果你可以在他的猴子补丁加载之前加载一些代码,那么你可以给方法取别名。

class Fixnum
  alias_method :original_plus, :+
end

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

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

【讨论】:

  • 如果您可以访问源代码,您可以将代码直接放在同事的猴子补丁之前的同一个文件中。否则答案将取决于你的程序是如何被加载的。
  • 这与我想象的一样接近解决方案,但我不确定如何影响代码加载的顺序。我怎么能坚持在他的猴子补丁之前加载别名 - 只需做你在这里所做的事情?也就是说,在源代码的前面插入定义 - 真的只需要这样吗?
  • 假设您也可以访问他的代码库部分,只需将别名粘贴在他的猴子补丁正上方即可。
  • 除了 REST 场景,在 Ruby 协同工作的情况下,您不是总能访问源代码吗?
【解决方案2】:

我最近在 ruby​​flow 提要中看到了这一点 - 它是一个简单的库,可让您命名名为 aikidoka 的顶级常量。如果没有关于如何/什么被猴子修补的任何细节,很难提供帮助。理论上,尽管您可以使用这样的方法来命名该类的猴子补丁版本,以便您可以独立访问它和原始版本。

【讨论】:

  • 这是否需要您重构代码库以使用新名称 - Twitter::Mash 而不是 Mash?
  • 即使在上面回答的 alias_method 情况下,您几乎肯定必须用不同的名称引用其中一个版本,因为您以两种不同的方式定义相同的功能
【解决方案3】:

具体取决于更改的功能以及更改方式,但像 Jim Wienrich 的 BlankSlate 类这样的实现可能会有所帮助:

【讨论】:

    猜你喜欢
    • 2010-10-10
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    相关资源
    最近更新 更多