想到Enumerable。
這是您需要將其包含在模塊中的完美示例。如果你的班級定義了#each
,那麼只需加入一個模塊(#map
,#select
等)即可獲得很多好處。當我使用模塊作爲mixin時,這是唯一的情況 - 當模塊提供了幾個方法的功能時,在包含模塊的類中定義它。我可以爭辯說,這應該是一般情況下唯一的情況。
至於界定「靜態」的方法,更好的方法是:
module MyModule
def self.do_something
end
end
你並不真的需要調用#module_function
。我認爲這只是奇怪的遺留問題。
你甚至可以做到這一點:
module MyModule
extend self
def do_something
end
end
...但它不會很好地工作,如果你還希望包括模塊的某個地方。我建議避免它,直到你瞭解Ruby元編程的細微之處。
最後,如果你只是做:
def do_something
end
...它不會最終作爲一個全球性的功能,但作爲Object
私有方法(有沒有功能在Ruby中,只是方法)。有兩個缺點。首先,你沒有命名空間 - 如果你定義了另一個具有相同名稱的函數,那麼你將會在稍後得到一個函數。其次,如果您的功能按照#method_missing
執行,則在Object
中使用私有方法會影響它。最後,猴子修補Object
只是邪惡的業務:)
編輯:
module_function
可以在類似於private
的方式來使用:
module Something
def foo
puts 'foo'
end
module_function
def bar
puts 'bar'
end
end
這樣的話,你可以打電話Something.bar
,但不不是Something.foo
。如果在此調用module_function
後定義了任何其他方法,它們也可在未混合的情況下使用。
雖然我不喜歡它,但有兩個原因。首先,混入並具有「靜態」方法的模塊聽起來有點不妥。可能有些有效的情況,但不會經常發生。正如我所說的,我更喜歡將模塊用作名稱空間或混合使用,但不是兩者兼而有之。
其次,在本示例中,bar
也可用於在Something
中混合的類/模塊。我不知道什麼時候這是可取的,因爲任何方法使用self
,它必須混入或不混入,然後它不需要混入。
我認爲使用module_function
沒有通過該方法的名稱比使用更經常使用。 private
和protected
也一樣。
感謝您的解釋。我明白你爲什麼要混入一個模塊,我的問題更多的是關於什麼時候可以使用module_function。你有沒有什麼時間可以使用它? – 2012-07-19 00:40:36
這個最後一個例子中有'module_function'的另外一個例子:'private'函數'foo'不能從'bar'裏面訪問,因爲'foo'是一個實例方法(它沒有'self') ,只有當這個模塊在某個類中混合時纔可以調用它。當它是一個僅用於命名空間目的的獨立模塊時是不可能的。那麼如何擁有它呢?如何將模塊用於名稱空間並隱藏來自外部世界的一些實現助手函數,但允許它們通過其接口方法調用? – SasQ 2013-09-03 06:10:15