2012-04-06 10 views
7

test_module.rbRubyのmodule_functionは、モジュール上のクラスのメソッドのスタイルに呼び出さ呼び出すモジュールのプライベートメソッドは、エラーを示しているクラスからモジュールの機能を呼び出す

module MyModule 
    def module_func_a 
     puts "module_func_a invoked" 
     private_b 
    end 

    module_function :module_func_a 

    private 
    def private_b 
     puts "private_b invoked" 
    end 
    end 

    class MyClass 
    include MyModule 
    def test_module 
     module_func_a 
    end 
    end 

c = MyClass.new 
    c.test_module 

出力1:

$ ruby test_module.rb 
module_func_a invoked 
private_b invoked 

クラスメソッドスタイルのモジュールのモジュール機能を呼び出す

ma = MyModule.module_func_a 

出力2:

module_func_a invoked 
test_module.rb:5:in `module_func_a': undefined local variable or method `private_b' for MyModule:Module (NameError) 
from test_module.rb:31 

モジュールを含む出力1と出力2 から分かるようにモジュールのprivateメソッドがモジュール関数 から呼び出されたときには問題は発生しませんが、cモジュールのmodule関数を直接呼び出す場合lass method styleモジュール関数から呼び出されたモジュールのプライベートメソッドが見つかりません。

私は上記の動作の背後にある理由を理解できますし、モジュールメソッド(モジュールのプライベートメソッドを呼び出す)をクラスメソッドスタイルのモジュールで呼び出すことは可能ですか?可能であれば、私のコードで同じことをするためにはどんな整流が必要ですか?

答えて

6

あなたはクラスでモジュールが含まれている場合、すべてのモジュールのメソッドのは(もprivate_bメソッドを持っていMyClassからselfmodule_func_aでのポイント、)そのクラスに含まれますので、それは動作します。

自己はMyModuleを指していますが、これにはprivate_bメソッドがありません。あなたは、それは両方の方法を動作するように望んでいた場合は、に持っているのどちらかだけでなく、モジュール方式としてprivate_bを宣言するか、すべてのそれのメソッドは、モジュール方式となるように、単に、extend selfMyModuleに行を追加したいです。

+0

ありがとうございます。私はMyModuleに自分自身を拡張しようとしています。この場合、プライベートは余分に見えて何の効果もありません。そのような場合にプライベートメソッドを作成できません。たとえば、モジュールインスタンスやモジュール関数でのみ使用されるユーティリティメソッドを作成する必要があり、モジュールのユーザーに公開しないでください。 –

+0

それでは、委任を使用するのが好きな理由です。 – psyho

+2

@pysho - あなたが紹介した代表団の使い方の例を私に提供してくれますか? –

3

module_functionmodule_func_aはメタクラスにコピーされますが、依存関係はコピーされません。

オブジェクトからmodule_func_aを呼び出すと、もう1つの方法private_bが表示されます。しかし、private_bはモジュールの機能ではないので、モジュール自体を呼び出すことはできません。

あなたもprivate_bためmodule_functionを使用する必要があり、それが動作するはずです。

関連する問題