为什么人们使用 `Module.send(:prepend, …)`?

Why do people use `Module.send(:prepend, …)`?

我正在学习如何在我的 Ruby 代码中使用 Module.prepend 而不是 alias_method_chain,并且我注意到有些人使用 send 来调用它(example):

ActionView::TemplateRenderer.send(:prepend,
    ActionViewTemplateRendererWithCurrentTemplate)

而别人直接调用(example):

ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate)

而且,虽然我还没有看到任何人使用这种样式,但我从文档中怀疑您甚至可以在您要添加的模块中编写它:

module ActionViewTemplateRendererWithCurrentTemplate
    # Methods you're overriding go here

    prepend_features ActionView::TemplateRenderer
end

这三种风格有区别吗?有理由偏爱其中之一吗?

Module#prependaddedRuby 版本 2.0.0.

它最初是作为 private 方法添加的,预期用例采用以下格式:

module Foo
  # ...
end

class Bar
  prepend Foo

  # ... The rest of the class definition ...
end

但是,很快就会发现,在许多情况下,人们希望在 class 之前添加一个模块,而不定义 class 的任何其他方面(在该部分代码中)。因此,以下模式变得普遍:

Bar.send(:prepend, Foo)

Ruby 版本 2.1.0 中,此问题已由 making Module#prepend a public method 解决 - 因此您现在可以简单地将其写为:

Bar.prepend(Foo)

但是,请注意,如果您编写的库需要支持 Ruby 2.0.0(即使 official support ended 于 2016 年 2 月 24 日发布),那么您必须坚持旧的 .send(:prepend, ...) 方法。

Module#include(从一开始就在 Ruby 语言中)在版本 <= 2.0.0 中也是私有方法,并在 [=] 中被制作成 public 15=].