为什么人们使用 `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#prepend
是 added 到 Ruby 版本 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=].
我正在学习如何在我的 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#prepend
是 added 到 Ruby 版本 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=].