【问题标题】:How can you influence the sequence in which Ruby code is loaded?你如何影响 Ruby 代码的加载顺序?
【发布时间】:2009-05-16 15:46:46
【问题描述】:

假设您的同事猴子修补了 Fixnum 类并重新定义 + 方法以减去而不是添加:

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

>> 5 + 3
=> 2

您的问题是您想访问 + 方法的原始功能。所以你把这段代码放在他之前的同一个源文件中。它将 + 方法别名为“original_plus”猴子修补它之前。

class Fixnum
  alias_method :original_plus, :+
end

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

现在可以通过 original_plus 访问 + 方法的原始功能

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

但我需要知道的是:

除了将它粘贴到他修改的同一个源文件中之外,还有其他方法可以在加载他的猴子补丁之前加载这个别名吗?

我的问题有两个原因:

  1. 我可能不想让他知道我已经这样做了
  2. 如果更改了源文件,使别名最终低于猴子补丁,则别名将不再产生所需的结果。

【问题讨论】:

  • 天哪,光是看着这只猴子补丁就让我畏缩。
  • @Ólafur - 我同意。尽管它提供了强大的功能,但猴子补丁确实打开了许多灾难性副作用的可能性。你必须问它是否真的值得。

标签: ruby monkeypatching


【解决方案1】:

当然。在你需要他的源文件之前在你的代码中粘贴anti-monkeypatch。

 % cat monkeypatch.rb
 class Fixnum
   def +(x)
     self - x
   end
 end
 % cat mycode.rb
 class Fixnum
   alias_method :original_plus, :+
 end
 require 'monkeypatch'
 puts 5 + 3 #=> 2
 puts 5.original_plus(3) #=> 8

【讨论】:

    【解决方案2】:

    Monkeypatching 可以很好地扩展现有类并添加新功能。 Monkeypatching 改变现有功能的行为简直太疯狂了!

    说真的,你应该和你的同事谈谈。

    如果像在您的示例中那样,他确实重新定义了现有方法只是为了改变其行为,您应该与他交谈并建议他使用alias_method_chain 以保存现有行为。

    【讨论】:

    • 不熟悉。那是Rails方法吗? (我这里只关心 Ruby。)
    • alias_method_chain 似乎是 alias_method 的同义词(据我所知)。所以,从这个意义上说,是的,我同意你的看法,他应该不理会 + 方法,而是将其别名为 coworker_plus。这样我就可以访问原始文件了。但是我们并不总是能够控制我们的同事做什么,不是吗?有时他们碰巧在政治上更有影响力和霸气,比如说(例如)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多