8

test_module.rb

  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からわかるように、モジュールのプライベートメソッドがモジュール関数から呼び出されても、クラスメソッドスタイルでモジュールのモジュール関数を直接呼び出す場合は問題は発生しません。モジュール関数から呼び出されたモジュールのプライベートメソッドが見つかりません。

上記の動作の背後にある理由と、クラスメソッドスタイルのモジュールでモジュール関数(モジュールのプライベートメソッドを呼び出す)を呼び出すことが可能かどうかを誰かに理解させることができますか?可能であれば、同じことを行うためにコードでどのような修正が必要ですか?

4

2 に答える 2

7

モジュールをクラスに含めると機能します。これは、モジュールのすべてのメソッドがそのクラスに含まれるためです(selfinは、をmodule_func_a指しMyClass、これにはprivate_bメソッドも含まれます)。

MyModule他の状況では、selfはprivate_bメソッドを持たないを指します。両方の方法で機能させたい場合はprivate_b、モジュールメソッドとしても宣言するか、単に行extend selfMyModuleに追加して、すべてのメソッドがモジュールメソッドになるようにする必要があります。

于 2012-04-06T11:34:59.847 に答える
3

module_functionmodule_func_aをメタクラスにコピーしますが、その依存関係はコピーしません。

したがってmodule_func_a、オブジェクトから呼び出すと、他のメソッドを取得しますprivate_b。ただし、はモジュール関数ではないため、モジュール自体で呼び出すと失敗しprivate_bます。

module_functionprivate_bも使用する必要があり、機能するはずです。

于 2012-04-06T11:32:50.330 に答える