Подтвердить что ты не робот

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>'

Где моя ошибка?

4b9b3361

Ответ 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" - это метод экземпляра.