在 ruby 中,我知道可以使用 module_function
在模块中混合使用模块函数,如此处所示。我知道这是多么有用,因此您可以在不混入模块的情况下使用该函数。
module MyModule
def do_something
puts "hello world"
end
module_function :do_something
end
我的问题是为什么您可能希望以这两种方式定义函数。
为什么不拥有
def MyModule.do_something
或
def do_something
在什么样的情况下,将函数混入或用作静态方法会有用?
最佳答案
想到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
上的私有(private)方法(Ruby 中没有函数,只有方法)。有两个缺点。首先,您没有命名空间——如果您定义了另一个具有相同名称的函数,那么它就是您获得的稍后被评估的函数。其次,如果您有根据 #method_missing
实现的功能,则在 Object
中使用私有(private)方法会隐藏它。最后,猴子修补 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
比 with 更常用。 private
和 protected
也是如此。
关于ruby module_function 与包含模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11550213/