在Ruby中,我理解模块函数可以通过使用module_function
而不用在模块中混合使用,如这里所示。我可以看到这是如何有用的,所以你可以使用函数,而不会在模块中混合。
module MyModule
def do_something
puts "Hello, World!"
end
module_function :do_something
end
为什么要用这两种方式定义函数?
为什么不干脆
def MyModule.do_something
或
def do_something
在什么样的情况下,将函数混合在其中或用作静态方法是有用的?
3条答案
按热度按时间e5nqia271#
想想Enumerable。
这是一个完美的例子,当你需要将它包含在一个模块中。如果你的类定义了
#each
,那么仅仅通过包含一个模块(#map
,#select
等)就可以得到很多好处。这是我使用模块作为mixin的唯一情况-当模块提供一些方法的功能时,在类中定义,您包括模块。我可以说,这应该是唯一的情况一般。至于定义“静态”方法,更好的方法是:
你真的不需要调用
#module_function
。我认为这只是奇怪的遗产的东西。你甚至可以这样做:
.但是如果您还想在某个地方包含模块,则它将无法正常工作。我建议在您了解Ruby元编程的微妙之处之前避免使用它。
最后,如果你只是这样做:
.它不会最终成为一个全局函数,而是作为
Object
上的私有方法(Ruby中没有函数,只有方法)。有两个缺点。首先,你没有命名空间--如果你用相同的名字定义另一个函数,它是你得到的那个稍后被计算的函数。第二,如果您有根据#method_missing
实现的功能,那么在Object
中使用私有方法将隐藏它。最后,猴子修补Object
只是邪恶的业务:)编辑:
module_function
可以以类似于private
的方式使用:这样,您可以调用
Something.bar
,但不能调用Something.foo
。如果在调用module_function
之后定义任何其他方法,它们也可以使用,而不会混入。我不喜欢它有两个原因。首先,混合在其中并具有“静态”方法的模块听起来有点不可靠。可能会有有效的案例,但不会那么频繁。正如我所说的,我更喜欢使用模块作为名称空间或将其混合使用,但不是两者兼而有之。
其次,在这个例子中,
bar
也可以用于混合在Something
中的类/模块。我不确定这是什么时候需要的,因为要么方法使用self
,它必须混合,要么不使用,然后它不需要混合。我认为使用
module_function
而不传递方法名称比使用。private
和protected
也是如此。csbfibhn2#
这是Ruby库提供不使用(太多)内部状态的功能的好方法。因此,如果你(例如)想要提供一个
sin
函数,并且不想污染“全局”(Object
)命名空间,你可以将其定义为常量(Math
)下的类方法。然而,想要编写数学应用程序的应用程序开发人员可能需要每两行
sin
。如果该方法也是一个示例方法,她可以只包含Math
(或My::Awesome::Nested::Library
)模块,现在可以直接调用sin
(stdlib示例)。这实际上是为了让图书馆对用户更舒适。如果他们希望你的库的功能在顶层,他们可以自己选择。
顺便说一下,你可以通过使用以下命令实现类似于
module_function
的功能:extend self
(在模块的第一行)。在我看来,它看起来更好,让事情更容易理解。**更新:**更多背景信息在this blog article中。
2izufjch3#
如果你想看一个工作示例,请查看Chronic gem中的handlers.rb。
处理程序被包含在parser.rb的Parser类中。
它使用 module_function 将方法从Handlers发送到特定的示例,并使用该示例的invoke方法。