想想Enumerable。
这是何时需要将其包含在模块中的完美示例。如果您的类定义了,那么只需包含一个模块( 、等)#each
,您就会获得很多好处。这是我将模块用作 mixins 的唯一情况 - 当模块根据一些方法提供功能时,在包含模块的类中定义。我可以争辩说,这应该是一般情况下的唯一情况。#map
#select
至于定义“静态”方法,更好的方法是:
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
。