gpt4 book ai didi

ruby module_function 与包含模块

转载 作者:数据小太阳 更新时间:2023-10-29 06:21:51 25 4
gpt4 key购买 nike

在 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 更常用。 privateprotected 也是如此。

关于ruby module_function 与包含模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11550213/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com