Reputation: 7622
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)
Upvotes: 33
Views: 24484
Reputation: 2000
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 ...
)
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.
Upvotes: 7
Reputation: 17793
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)
Upvotes: 25
Reputation: 138042
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.
Upvotes: 14
Reputation: 2491
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.
Upvotes: 3