Rails 中的猴子补丁

发布于 2024-10-02 12:15:10 字数 1431 浏览 8 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦萦几度 2024-10-09 12:15:10

一般来说,猴子修补从来都不是一个好的做法。然而,我经常将它用于与应用程序不同的非常特殊的情况。在所有其他情况下,我更喜欢分叉 gem 或插件,并将分叉的 gem 直接安装到我的应用程序的 gems 文件夹中。

我还有一些工具模块,它们对一些类进行猴子修补,以将特殊目的行为注入到一些标准类中,以便在不同的应用程序中重用 - 但这些仍然足够特殊,对公众没有用处,或者创建它是不可行的叉子。

所以最终这是一个专业化和兼容性的决定。请始终记住,猴子修补更有可能破坏您可能在项目中使用的其他插件或 gem 的预期行为。在更新工作应用程序生态系统(或外部支持生态系统,如 Rails 及其依赖项)中的组件后,这种情况可能会变得更加紧迫。

In general, monkey patching is never a good practice. However, I often use it for very special cases distinct to the application. In all other cases I'd prefer forking the gem or plugin and install the forked gem right into the gems folder of my application.

I'm also having a few tools modules which monkey patch some classes to inject special purpose behaviour into some standard classes for reuse in different application - but these are still special enough to not be useful to the public, or it is just infeasible to create forks.

So in the end it's a decision of specialization and compatibility. Always keep in mind that monkey patching is more likely going to break expected behaviour of other plugins or gems you may use in your project. This may become even more imminent after updating components in your working application ecosystem (or the outer supporting ecosystem, like Rails and its dependencies).

浮华 2024-10-09 12:15:10

如果您练习负责任的鸭子打孔,那么它可以像支持宝石的特定于项目的本地副本一样容易。这完全取决于您对任一解决方案的升级问题进行记录的努力。很容易说,一年后您或支持开发人员都不会鲁莽地替换供应商/宝石中的该宝石,但这种情况确实发生了。分叉项目,在本地修补它,然后提交拉取请求并将其返回到主 gem 中是理想的情况。

如果你选择这条路线,你需要遵守一些关于鸭子拳击的规则:

  • 补丁必须位于明显明显的位置。 lib/[gem_name]_extensions.rb 将是我作为支持开发人员检查缺陷时首先查看的位置。
  • 该补丁应该有大量的文档。它应该概述潜在的升级噩梦。
  • 补丁应该在不同的模块上完成,然后包含到原始模块/类 ActiveSupport 样式中。这允许支持开发人员调用 Problem_method.ancestors 并查看正在进行的猴子补丁。

这将是一种保留旧方法(为了乐趣和游戏)并允许您使用 Problem_method.ancestors() 更轻松地跟踪它的方法。

#lib/mongomapper_extensions.rb
module MongomapperExensions
  module ProblemClassExensions
    alias :old_problem_method :problem method
    def problem_method
      #guerilla code goes here!
    end
  end
end
class ProblemClass
  include MongoMapperExtensions::ProblemClassExtensions
end

If you practice responsible duck punching, it can be as easy to support as a project specific local copy of a gem. It depends entirely on your diligence documenting upgrade problems with either solution. It's easy to say that either you or a support developer wouldn't recklessly replace that gem in vendor/gems a year from now, but it happens. Forking the project, patching it locally, and then submitting a pull request and having it make it back into the main gem is the ideal situation.

You need to stick to a couple of rules on duck punching though if you elect this route:

  • The patch has to sit in a blatantly obvious location. lib/[gem_name]_extensions.rb would be where I would first look as a support developer checking out a defect.
  • The patch should have a large amount of documentation surrounding it. It should outline potential upgrade nightmares.
  • The patch should be done on a different module that is then included into original module/class ActiveSupport style. This allows a support dev to call problem_method.ancestors and see a monkeypatch in progress.

This would be a way to do it in a way that keeps the old method around (for fun and games) and allows you to trace it more easily with a problem_method.ancestors().

#lib/mongomapper_extensions.rb
module MongomapperExensions
  module ProblemClassExensions
    alias :old_problem_method :problem method
    def problem_method
      #guerilla code goes here!
    end
  end
end
class ProblemClass
  include MongoMapperExtensions::ProblemClassExtensions
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文