Ruby - Module :: NoMethodError

22,849

Solution 1

Apart from the answers that give you the option of defining the function as self., you have another option of including the module and calling it without the module reference like this:

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

and you can call it like this:

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

Solution 2

The easiest way is to turn your method into a module-level method:

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 would also work, because at the time that line is run, self is the module definition.

Solution 3

Next to the answers here you also can do the following:

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

The class << self block will define also every method in it as instance methods of your module.

(It's functionality is the same like to define every single methods by def Prober.mymethod ... or def self.mymethod ...)


Update (2014-11-22)

According to the Ruby Style Guide you should use module_function instead:

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

I'd call this utility modules.

BTW: In the past it was more common to use extend self instead of wrapping the methods in a class << self block.

I also adapted the code above to other style guide recommendations.

Solution 4

The answer is:

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)

Because otherwise you define the method as an instance method of the module, but you actually want to define it statically.

Share:
22,849
Sayuj
Author by

Sayuj

Updated on November 22, 2020

Comments

  • Sayuj
    Sayuj over 3 years

    I have a module like this:

    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
    

    And I am trying to access this from my main program like this:

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

    But it generate error:

    undefined method `probe_invoke' for Prober:Module (NoMethodError)