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

В чем разница между "включить модуль" и "расширить модуль" в Ruby?

Возможный дубликат:
В чем разница между включением и расширением в Ruby?

Учитывая:

module my_module
  def foo
    ...
  end
end

Вопрос 1

В чем разница между:

class A
  include my_module
end

и

class A
  extend my_module
end

Вопрос 2

Будет ли foo рассматриваться как метод экземпляра или метод класса? Другими словами, это эквивалентно:

class A
  def foo
    ...
  end
end

или:

class A
  def self.foo
    ...
  end
end

?

4b9b3361

Ответ 1

Я написал сообщение в блоге об этом давным-давно здесь.

Когда вы включаете "модуль", модуль включается так, как если бы методы были определены в классе, включающем их, вы могли бы сказать, что он копирует методы в класс включения.

Когда вы "расширяете" модуль, вы говорите "добавьте методы этого модуля в этот конкретный экземпляр". Когда вы находитесь внутри определения класса и говорите "расширяете", "экземпляр" - это сам объект класса, но вы также можете сделать что-то подобное (как в моем сообщении в блоге выше):

module MyModule
  def foo
    puts "foo called"
  end
end

class A
end

object = A.new
object.extend MyModule

object.foo #prints "foo called"    

Итак, это не совсем метод класса, а метод к "экземпляру", который вы назвали "расширяем". Поскольку вы делаете это внутри определения класса, и экземпляр в нем есть сам класс, он "похож" на метод класса.

Ответ 2

1) include добавляет методы, константы и переменные в экземпляры класса A; extend добавляет эти вещи к экземпляру Class instance A (эффективно определяя методы класса).

include my_module позволит следующее: A.new.foo

extend my_module позволит: A.foo

В общем случае include имеет смысл только в Class или Module, а extend может использоваться для добавления методов к любому Object.

2) По сути: при использовании include foo является методом экземпляра A... при использовании extend, foo является методом класса.