2012-02-13 16 views
1

好像如果你正在寻找能够调用一个模块(/班),你正在寻找一个单身方法......如果是这样的话,你使用类方法或Singleton的更好mixin(不寻找答案,哪一个是“更好”)。Module#module_function被认为是坏的吗?

唯一的好处(?)我可以使用#module_function看到的是模块以及模块上调用方法在混合的灵活性。还有别的事吗?

我发现一些旧代码,用来工作< 1.9.3跑,但不会再和我期待解决。它看起来是这样的:

module MyThing 
    def self.do_something 
    ... 
    end 
end 

...并允许:

MyThing.do_something 

我并不想争辩说,这样的设计是一个很好的 - 只是试图找出什么最好的办法是解决它。倾向于一个标准模块...

更新...

我错误地简化了我的问题和榜样。我正在经历的不同行为是在我的RSpec测试期间 - 他们通过使用RSpec 2.8.0和MRI 1.9.2,但通过MRI 1.9.3失败。该模块的样子:

module MyThing 
    module SubThing 
    module SubSubThing 
     def self.do_something 
     ... 
     end 
    end 
    end 
end 

...和测试:

describe MyThing::SubThing::SubSubThing do 
    include MyThing::SubThing 

    describe "#do_something" do 
    it "does something" do 
     SubSubThing.do_something 
    end 
    end 
end 

在1.9.3下运行的规范,我得到NameError: uninitialized constant DataGathering;在1.9.2下,他们通过。这导致我错误地诊断问题,并呈现我在上面做了什么。好像include行为在1.9.3中不同。没关系;我的问题仍然存在:#module_function提供了一些特别的东西吗?

+2

你举的例子在这里工作 - 运行红宝石1.9.3dev(2011-09-23修订33323)x86_64的-darwin11.0.0。 – user2398029 2012-02-13 19:10:25

+0

感谢您的检查;这让我意识到我错误地诊断了这个问题。我已更新以描述真正的问题。 – turboladen 2012-02-13 21:48:20

+1

FWIW,看起来像我的1.9.2 v。1.9。3问题被记录为[1.9.3错误](http://bugs.ruby-lang.org/issues/5657)(最初[由Matz记录](http://bugs.ruby-lang.org/issues/4536)),但结果是一个1.9.2的错误。去搞清楚。 – turboladen 2012-02-14 00:54:59

回答

3

module_function目的正是你在你的问题中提到:它给你的灵活性,显式调用模块类方法,使用模块名,或给它的混合,使事情更简洁一点。

你也可以做extend self同样的事情(模块定义中)。不同之处在于,如果混合使用module_function的模块,混合方法将变为私有实例方法(但它们将是声明模块的公共类方法);如果你使用extend self,他们将拥有的任何访问限定符在模块定义中使用,既混合,并当模块作为类方法的直接调用。

+0

我只是在'irb'中做了一些快速测试,并更正了我的答案。 – 2012-02-13 22:31:29

+0

回头看这篇文章,我可以补充一点,我认为'Singleton' mixin(因为OP提到它)几乎没用。如果你想要一个“singleton”,只需创建一个新对象(使用Object.new'),并定义你需要的任何方法。 – 2013-01-19 19:01:23

0

Ruby中的模块抽象地等同于C++中的Namespace。这应该对Ruby 1.9.3罚款:

module MyThing 
    def MyThing.do_something 
     # ... 
    end 
end 

do_something也可以作为MyThing的实例方法,这就是事情变得明朗实施。

+0

你是对的;我错误地描述了我的问题。相应更新。 – turboladen 2012-02-13 21:47:34

相关问题