Возможно, я четко проясню то, что, по моему мнению, не полностью и явно адресовано прекрасному ответу Йорга (с величайшим уважением) тем, кто не знаком с « объектной моделью » Ruby:
module Country
def location
puts "location"
end
def self.included(base)
def cities
puts "cities"
end
end
def self.extended(base)
puts "#{self}" ## NOTICE THIS NEW LINE! NEW LINE
def animals
puts "animals"
end
end
end
class Test
include Country
end
class Test2
extend Country
end
Test.new.animals
В чем проблема?
Мы расширяем Test2, не так ли? Как же тогда метод животных определен в Тесте 1?
Ключ должен добавить строку puts "#{self}
над методом животных.
Здесь мы видим, что метод животных определен в Страновой модуль. Так что на самом деле, когда вы думаете, что расширяете, вы на самом деле убедитесь, что он добавлен как метод экземпляра, а не как «метод класса stati c» (если вы исходите из c# / java фон). Строго говоря, это не совсем точно: когда вы «расширяете» таким образом - и если вы делаете это правильно - вы фактически добавляете метод в одноэлементный класс Test2. В этом отношении объектная модель Ruby немного сложна. Метод класса stati c - это метод, ДОБАВЛЕННЫЙ в одноэлементный класс класса. Что такое одноэлементный класс? Теперь вы попадаете в объектную модель ruby. Это сложно и требует утечки мозгов, но как только вы это поймете, вы сможете делать некоторые довольно мощные (и опасные?) Вещи, такие как: исправление обезьян.
Решение:
говорит Йорг. это лучше, чем я мог. вам нужно определить животных следующим образом: def base.animals
.