【问题标题】:Is a bad practice to monkey patch a base ruby class?猴子修补基础红宝石类是一种不好的做法吗?
【发布时间】:2013-04-30 18:27:59
【问题描述】:

我正在开发一个 ruby​​ 项目,我们计划在其中使用 ruby​​ 字符串进行一些操作。有些操作很简单(比如计算单词的数量),有些则比较复杂(比如检查给定字符串的语言是否正确)。

实现这一点的一种可能方法是使用额外的方法修补String 类,不修改任何现有方法,并添加"some string".word_count"some string".cjk? 等行为。

基于FileUtils 的另一种方法是创建一个充满方法的类或模块,并始终使用字符串作为参数,例如OddClassName.word_count("some string")OddClassName.cjk?("some string")。由于可读性,我们更喜欢第一个。

我知道猴子修补第一个替代方案中描述的基本类可能会发生名称冲突。但是,如果这是主应用程序,而不是库,我应该担心它吗?

所以,问题是:

  • 向 ruby​​ 基类添加方法是一种不好的做法吗?如果是,是在所有情况下还是仅在某些情况下?
  • 完成此任务的最佳方法是什么?
  • “OddClassName”的名称可能是什么?

请提出任何替代方案。

【问题讨论】:

  • 您使用的是哪个版本的 Ruby?我相信 2.0 中有一些不同的猴子补丁选项
  • @CharlesCaldwell 我使用的是 1.9,但如果适合,也可以在您的答案中添加 2.0。
  • 您不需要使用标题来标记问题中的部分。 StackOverflow 的外观和感觉更具对话性且不那么正式。删除标题,您的问题将非常顺利。不过,请务必将“Ruby”之类的专有名称大写。

标签: ruby monkeypatching


【解决方案1】:

Monkey 修补不被认为是一种不好的做法,除非您正在编写不具有 PatchedClass 相关行为的奇怪方法(例如,String.monkeyPatchForMakingJpegFromString 相当糟糕,但 Jpeg.fromString 已经足够好了。)

但是如果您的项目相当大,您在其中使用的库可能碰巧有冲突补丁,因此您可能会遇到所有这些补丁内容的更多问题。在 Ruby 2.0 中,改进 可以提供帮助。它们的工作方式如下:您在其中定义一个modulerefine 您的(甚至是核心)类,然后在需要的地方使用该模块。因此,在您的代码中,它的工作方式如下:

YourClass.new.refinedMethodFromCoreClass #=> some result

但是

CoreClass.refinedMethodFromCoreClass

产生undefined method 异常。

这就是猴子补丁的全部内容:猴子补丁既有用又方便,但改进添加了一些功能,使您的代码更加安全、可维护和整洁。

【讨论】:

  • 感谢您的回答,您对此是否有任何参考:“猴子修补,基本上,不被认为是一种不好的做法”应用于基类?
  • interview w/ matz,第 6 个答案:
  • 谢谢,他似乎告诉你可以扩展基类,但没有告诉我们这是一个好习惯。无论如何都要考虑到这一点。
  • 我不知道你是否会觉得它足够,但 Rails 也确实使用它。所有这些 10.hours 等等。
【解决方案2】:

我会使用一个新类,将其称为Doc 或其他名称,因为获取字数和检查语言听起来像是文档操作。

让它接受一个字符串作为构造函数参数,并有修改链返回一个新的文档。还给它一个返回字符串的 to_s 方法。

class Doc
  def initialize(str)
    @str = str
  end

  def to_s
    @str
  end

  define word_count, cjk?, etc.
end

Doc.new("Some document").word_count
# => 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-23
    • 2010-11-17
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2016-10-30
    相关资源
    最近更新 更多