32

次のようなモジュールがあります。

module Prober
  def probe_invoke(type, data = {})
    p = Probe.new({:probe_type => type.to_s,
        :data => data.to_json, :probe_status => 0, :retries => 0})
    p.save
  end
end

そして、次のようにメインプログラムからこれにアクセスしようとしています:

require 'prober'
Prober.probe_invoke("send_sms", sms_text)

しかし、それはエラーを生成します:

Prober:Module のメソッド「probe_invoke」が未定義 (NoMethodError)

4

4 に答える 4

24

関数を として定義するオプションを提供する回答とは別にself.、モジュールを含めて、次のようにモジュール参照なしで呼び出すという別のオプションがあります。

module Prober
  def probe_invoke(type, data = {})
    p = Probe.new({:probe_type => type.to_s,
        :data => data.to_json, :probe_status => 0, :retries => 0})
    p.save
  end
end

次のように呼び出すことができます。

require 'prober'
include Prober
probe_invoke("send_sms", sms_text)
于 2011-06-01T08:54:16.537 に答える
14

最も簡単な方法は、メソッドをモジュール レベルのメソッドに変換することです。

module Prober
  def Prober.probe_invoke(type, data = {})
    p = Probe.new({:probe_type => type.to_s,
        :data => data.to_json, :probe_status => 0, :retries => 0})
    p.save
  end
end

def self.probe_invokeその行が実行された時点でselfモジュール定義であるため、これも機能します。

于 2011-06-01T07:23:52.793 に答える
7

ここの回答の次に、次のこともできます。

module Prober
  class << self
    def probe_invoke(type, data = {})
      p = Probe.new({:probe_type => type.to_s,
          :data => data.to_json, :probe_status => 0, :retries => 0})
      p.save
    end

    # more module instance methods ...
  end
end

ブロックは、その中のclass << selfすべてのメソッドもモジュールのインスタンス メソッドとして定義します。

(機能は、すべてのメソッドをdef Prober.mymethod ...orで定義するのと同じですdef self.mymethod ...)


更新 (2014-11-22)

Ruby Style Guide によると、代わりに次を使用する必要があります。module_function

module Prober
  module_function # <-- preferred style nowadays

  def probe_invoke(type, data = {})
    Probe.new(probe_type:   type.to_s,
              data:         data.to_json,
              probe_status: 0,
              retries:      0)
      .save # no need for a temporary variable
  end

  # more module methods ...
end

これをユーティリティモジュールと呼びます。

ところで: 以前は、メソッドをブロックextend selfでラップする代わりに使用する方が一般的でした。class << self

また、上記のコードを他のスタイル ガイドの推奨事項に適合させました。

于 2011-06-01T08:39:36.570 に答える
3

答えは次のとおりです。

module Prober
  def Prober.probe_invoke(type, data = {})
    p = Probe.new({:probe_type => type.to_s,
        :data => data.to_json, :probe_status => 0, :retries => 0})
    p.save
  end
end

Prober.probe_invoke("send_sms", sms_text)

それ以外の場合は、メソッドをモジュールのインスタンス メソッドとして定義しますが、実際には静的に定義したいためです。

于 2011-06-01T07:23:46.310 に答える