2017-01-03 105 views
4

我正在学习如何在我的Ruby代码使用Module.prepend代替alias_method_chain,我已经注意到,有些人使用send称呼它(example):为什么人们使用`Module.send(:prepend,...)`?

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

当别人直接调用它(example) :

ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate) 

而且,虽然我还没有看到任何人使用这种风格,我从文档怀疑,你甚至可以你从前面加上模块中这样写:

module ActionViewTemplateRendererWithCurrentTemplate 
    # Methods you're overriding go here 

    prepend_features ActionView::TemplateRenderer 
end 

这三种风格之间有一些区别吗?是否有理由支持他人?

+3

也许人们仍然会这样写,因为'老习惯',因为#include和#prepend在Ruby 2.1之前曾经是私有方法。 – Matheno

+1

'prepend_features'是一个被'prepend'调用的钩子方法,通常是* not *意图也不是被设计为直接调用。 –

回答

5

Module#prependadded红宝石版本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)需要的库,那么您不得不坚持旧的.send(:prepend, ...)方法。

Module#include(自从它开始以来一直使用Ruby语言)也是版本<= 2.0.0中的私有方法,并在2.1.0中公开。

相关问题