Ruby - Модуль :: NoMethodError - PullRequest
       24

Ruby - Модуль :: NoMethodError

27 голосов
/ 01 июня 2011

У меня есть такой модуль:

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)

Но выдает ошибку:

неопределенный метод `probe_invoke 'для Пробер: Модуль (NoMethodError)

Ответы [ 4 ]

23 голосов
/ 01 июня 2011

Помимо ответов, которые дают вам возможность определить функцию как 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)
14 голосов
/ 01 июня 2011

Самый простой способ - превратить ваш метод в метод уровня модуля:

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 является определением модуля.

7 голосов
/ 01 июня 2011

Рядом с ответами здесь вы также можете сделать следующее:

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 ... или def self.mymethod ...)


Обновление (2014-11-22)

Согласно руководству по стилям Ruby вы следует использовать 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.

Я также адаптировал приведенный выше код к другим рекомендациям руководства по стилю.

3 голосов
/ 01 июня 2011

Ответ:

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)

Потому что в противном случае вы определяете метод как метод экземпляра модуля, но на самом деле вы хотите определить его статически.

...