我在Ruby代码中学习如何使用Module.prepend
代替alias_method_chain
,并且我注意到有些人使用send
来调用它({ {3}}):
ActionView::TemplateRenderer.send(:prepend,
ActionViewTemplateRendererWithCurrentTemplate)
其他人直接称呼它(example):
ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate)
而且,虽然我还没有看到有人使用这种风格,但我怀疑从文档中你甚至可以在你以前的模块中写这个:
module ActionViewTemplateRendererWithCurrentTemplate
# Methods you're overriding go here
prepend_features ActionView::TemplateRenderer
end
这三种风格有什么区别吗?是否有理由支持其他人?
答案 0 :(得分:8)
Module#prepend
added至 Ruby版本2.0.0
。
它最初是作为私有方法添加的,其预期用例采用以下格式:
module Foo
# ...
end
class Bar
prepend Foo
# ... The rest of the class definition ...
end
然而,很快就会发现,在很多情况下,人们希望将模块添加到类中而不定义类的任何其他方面(在代码部分中)。因此,以下模式变得普遍:
Bar.send(:prepend, Foo)
在 Ruby版本2.1.0
中,此问题已由making Module#prepend
a public method解决 - 因此您现在只需将其写为:
Bar.prepend(Foo)
但是,请注意,如果您正在编写支持Ruby 2.0.0
所需的库(即使2016年2月24日official support ended),那么您必须坚持使用旧的{{1}方法。
.send(:prepend, ...)
(自成立以来一直使用Ruby语言)也是版本Module#include
中的私有方法,并在<= 2.0.0
中公开。