Ruby - Module :: NoMethodError

Say*_*yuj 27 ruby module nomethoderror

我有一个这样的模块:

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
Run Code Online (Sandbox Code Playgroud)

我试图从我的主程序中访问这个:

require 'prober'
Prober.probe_invoke("send_sms", sms_text)
Run Code Online (Sandbox Code Playgroud)

但它会产生错误:

Prober的未定义方法`probe_invoke':模块(NoMethodError)

rub*_*nce 23

除了给你选择定义函数的答案之外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
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它:

require 'prober'
include Prober
probe_invoke("send_sms", sms_text)
Run Code Online (Sandbox Code Playgroud)

  • 需要文件将获取模块的代码.但它将在模块名称空间内.如果该方法被声明为`def self.probe_invoke(type,data = {})`,那么代码就像`require'prober'; Prober.probe_invoke("send_sms",sms_text)`,因为我们将该方法声明为模块方法(类级方法).但是在这里我已经将该方法声明为模块的实例方法.由于无法实例化模块,因此通过包含模块来使用这些方法.通过包含模块,模块的所有实例方法都将添加到当前范围. (5认同)

Gar*_*eth 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
Run Code Online (Sandbox Code Playgroud)

def self.probe_invoke也可以工作,因为在运行该行时,self是模块定义.


asa*_*aki 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
Run Code Online (Sandbox Code Playgroud)

class << self块还将其中的每个方法定义为模块的实例方法.

(它的功能与通过def Prober.mymethod ...或定义每个方法相同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
Run Code Online (Sandbox Code Playgroud)

我叫这个实用工具模块.

BTW:在过去,更常见的是使用extend self而不是将方法包装在一个class << self块中.

我还将上面的代码改编为其他样式指南建议.