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 (NoMethodError) 的未定义方法“probe_invoke”

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 回答