Ruby: модуль, требует и включает
Я пытаюсь использовать модули Ruby (mixins).
У меня есть test.rb:
#!/usr/bin/env ruby
require_relative 'lib/mymodule'
class MyApp
include MyModule
self.hallo
end
и lib/mymodule.rb:
module MyModule
def hallo
puts "hallo"
end
end
Довольно простая настройка. Но это не работает:(:
ruby test.rb
test.rb:8:in `<class:MyApp>': undefined method `hallo' for MyApp:Class (NoMethodError)
from test.rb:6:in `<main>'
Где моя ошибка?
Ответы
Ответ 1
Короче: вам нужно extend
вместо include
модуля.
class MyApp
extend MyModule
self.hallo
end
include
предоставляет методы экземпляра для класса, в котором он находится.
extend
предоставляет методы класса для класса, в котором он находится.
Дайте этот прочитанный.
Ответ 2
Проблема заключается в том, что вы вызываете hallo
в определении класса, в то время как вы добавляете его как метод экземпляра (include
).
Итак, вы можете использовать extend
(hallo
станет методом класса):
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
extend MyModule
self.hallo
end
Или либо вызовите hallo
в экземпляре MyApp:
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
include MyModule
end
an_instance = MyApp.new
an_instance.hallo
Ответ 3
Ваш код работает, но в том числе модуль не делает то, что, по вашему мнению, он делает. Класс, включая модуль, не получит методы - объекты из этого класса будут.
Итак, это сработает:
class MyApp
include MyModule
end
my_app_object = MyApp.new
my_app_object.hallo # => hallo
my_app_object - это объект класса MyApp, в котором есть миксы модуля MyModule. Посмотрите там для полного объяснения модулей и микшинов.
Ответ 4
class MyApp
class << self
include MyModule
end
self.hallo
end
совпадает с
class MyApp
extend MyModule
self.hallo
end
extends только открывает объект класса и включает методы модуля. "hallo" становится классом объекта aka. статический метод класса MyApp.
Итак, "включите", приведите методы к экземплярам приемника, в вашем случае "я" НЕ к самому объекту. "продлить" вводят методы в приемник в вашем случае "я".
self.include MyModule // inject the methods into the instances of self
self.extend MyModule // inject the methods into object self
На уровне класса "self" будет указывать на объект класса, который является MyApp.
Также помните, что "include" и "extend" - это просто методы, определенные в module.rb.
"include" - это метод объекта класса (static-method), а "extend" - это метод экземпляра.