想想Enumerable.
这是您需要将其包含在模块中的最佳示例.如果你的类定义了#each
,那么只需包含一个模块(#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
之后定义了任何其他方法,那么它们也可以在没有混合的情况下使用.
不过,我不喜欢它有两个原因.首先,混合使用"静态"方法的模块听起来有点诡异.可能会有有效的 case ,但不会经常出现.正如我所说的,我更喜欢使用模块作为名称空间,或者将其混合在一起,但不能两者兼而有之.
其次,在本例中,bar
也可用于混合在Something
中的类/模块.我不确定这是什么时候需要的,因为要么该方法使用self
,必须混合,要么不使用,然后就不需要混合.
我认为使用module_function
而不传递方法名称的情况比使用module_function
更常见.private
和protected
也是如此.