2017-01-03 93 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中公開。

相關問題