2012-02-13 14 views
1

モジュール(/クラス)のメソッドを呼び出せるようになっているのであれば、シングルトンを探しているようですね...そうだとすれば、クラスメソッドを使うほうが良いでしょうか、Singletonミックスイン(どちらが「より良い」という答えを探していない)。Module#module_functionの使用が悪いと考えられていますか?

#module_functionを使用した場合の唯一の利点(?)は、モジュール内で混合したり、モジュール上でメソッドを呼び出したりする柔軟性です。他に何かありますか?

私は< 1.9.3で動作していたいくつかの古いコードを実行しましたが、これ以上修正する予定はありません。ちょうどかを把握しようとしている - 私はこのデザインは良いものだったと主張するつもりはないよ

MyThing.do_something 

:それはこのような何かに見えた:

module MyThing 
    def self.do_something 
    ... 
    end 
end 

を...とに許可します最善の方法はそれを修正することです。標準モジュールに傾いて...

更新...

私が間違って私の問題と例を簡略化したいです。私が経験している異なる動作は、RSpecテスト中です.MRS 1.9.2でRSpec 2.8.0を使用していますが、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

ここではRuby 1.9.3dev(2011-09-23 revision 33323)[x86_64-darwin11.0.0]を実行しています。 – user2398029

+0

ありがとうございます。それは私が間違って問題を診断したことを実感しました。私は本当の問題を説明するように更新しました。 – turboladen

+1

FWIWは、1.9.2対1.9のように見えます。3の問題は、[1.9.3バグ](http://bugs.ruby-lang.org/issues/5657)(元々は[Logz Matz](http://bugs.ruby-lang.org/issues)/4536))、1.9.2バグであった。 Go figure。 – turboladen

答えて

3

module_functionの目的は、モジュールでクラスメソッドを明示的に呼び出したり、モジュール名を使用したり、モジュール名を混在させたり、より簡潔にする柔軟性を与えます。

extend self(モジュール定義内)でも同じことができます。違いは、module_functionを使用するモジュールで混在すると、混在メソッドはprivateインスタンスメソッドになります(宣言モジュールのパブリッククラスメソッドになります)。 extend selfを使用すると、モジュール定義で使用されたアクセス修飾子はどれも、と混在している場合と、クラスメソッドとしてモジュールで直接呼び出されたときの両方になります。

+0

私は 'irb'でいくつかの簡単なテストを行い、答えを修正しました。 –

+0

この記事を振り返ってみると、私は「シングルトン」ミックスインが(OPがそれを述べたので)ほとんど役に立たないと思うと付け加えるかもしれません。 「シングルトン」が必要な場合は、(Object.newを使用して)新しいオブジェクトを作成し、必要なメソッドを定義してください。 –

0

Rubyのモジュールは、C++のNamespaceと抽象的な同等です。これは、Ruby 1.9.3の罰金する必要があります:

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

do_somethingまた、物事が暗い取得する場所ですMyThingのインスタンスメソッドとして実装することができます。

+0

あなたは正しいです。私は間違って私の問題を説明した。それに応じて更新。 – turboladen

関連する問題