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
И я пытаюсь получить доступ к этому из моей основной программы следующим образом:
require 'prober'
Prober.probe_invoke("send_sms", sms_text)
Но он генерирует ошибку:
undefined метод `probe_invoke 'для Prober: модуль (NoMethodError)
Ответы
Ответ 1
Помимо ответов, которые дают вам возможность определить функцию как 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)
Ответ 2
Самый простой способ - превратить ваш метод в метод уровня модуля:
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
- это определение модуля.
Ответ 3
Рядом с ответами вы также можете сделать следующее:
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
Я бы назвал это служебные модули.
BTW: Раньше чаще всего использовалось extend self
вместо того, чтобы обертывать методы в блоке class << self
.
Я также применил приведенный выше код к другим рекомендациям руководства по стилю.
Ответ 4
Ответ:
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)
Потому что иначе вы определяете метод как метод экземпляра модуля, но вы действительно хотите его статически определить.