В чем разница между include и require в Ruby?

465

Мой вопрос похож на «В чем разница между включением и расширением в Ruby? ».

Какая разница между requireи includeв Ruby? Если я просто хочу использовать методы из модуля в моем классе, я должен requireэто или includeнет?

Оуэн
источник
1
Для чего это стоит, вот ссылки на документацию сообщества для requireи include, а также соответствующих, Module#append_features.

Ответы:

543

В чем разница между «включать» и «требовать» в Ruby?

Ответ:

Методы include и require делают совершенно разные вещи.

Метод require делает то, что include делает в большинстве других языков программирования: запускает другой файл. Он также отслеживает то, что вам требовалось в прошлом, и не будет требовать один и тот же файл дважды. Чтобы запустить другой файл без этой дополнительной функциональности, вы можете использовать метод загрузки.

Метод include берет все методы из другого модуля и включает их в текущий модуль. Это вещь на уровне языка, а не на уровне файла, как с require. Метод include - это основной способ «расширить» классы с помощью других модулей (обычно их называют «надстройками»). Например, если ваш класс определяет метод «each», вы можете включить в него модуль mixin Enumerable, и он может действовать как коллекция. Это может сбивать с толку, так как глагол включения используется совсем по-другому в других языках.

Источник

Так что, если вы просто хотите использовать модуль, а не расширять его или делать встраивание, тогда вы захотите его использовать require.

Как ни странно, Руби requireаналогична Кассиопеяне include, в то время как Руби includeпочти ничего , как Кассиопеяне include.

HanClinto
источник
45
На самом деле C включает, не загружает файл, как требуется do, а вместо этого заменяет строку #include содержимым файла. Включенные файлы не обязательно должны быть 'header', а #include не обязательно должно быть в начале файла, но может быть где угодно, например, в классе или даже в определении метода. Это означает, что вы можете делать mixin в C ++, записывая некоторые методы в файл и включая его в код класса, точно так же, как в ruby. Так что они не так далеко, хотя это действительно не обычная практика в Си.
mb14
13
Этот ответ может быть полезным, включая примеры.
Трэвис Беар
12
Комментарий mb14 подразумевает это, но он явно заявляет: вопреки тому, что говорится в ответе, require не «запускает» файл, а загружает его так, как если бы он был частью содержащего файла. Это может показаться семантической придиркой, но на самом деле это довольно важное различие.
Lonny Eachus
Отличное объяснение. Спасибо за то, что высказали мысль с последним утверждением: «Как ни странно, требование Ruby аналогично включению C, в то время как включение Ruby почти не похоже на включение C».
АртСабинцев
1
@GregSchmit: includeв Ruby это просто наследование. class C; include M endделает Mсуперкласс Cи (бывший) суперкласс Cсуперкласса M. Я не думаю, что Си includeработает через наследование, я думаю, что это простая текстовая / лексическая замена.
Йорг W Mittag
100

Если вы используете модуль, это означает, что вы вводите все методы в свой класс. Если у вас extendкласс с модулем, это означает, что вы «вводите» методы модуля как методы класса . Если у вас includeкласс с модулем, это означает, что вы «вводите» методы модуля в качестве методов экземпляра .

EX:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => неопределенный метод 'say' для B: Class

B.new.say => это модуль А

C.say => это модуль А

C.new.say => неопределенный метод 'say' для C: Class

Питер Данг
источник
23
Я думаю, что это не отвечает на вопрос, но это то, что я искал =)
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
2
Это на самом деле не отвечает на вопрос о том, каковы различия между requireи include.
94

Из книги Метапрограммирования Ruby,

require()Метод очень похож load(), но это означало для различных целей. Вы используете load()для выполнения кода, и вы используете require()для импорта библиотек.

Пратик Хадлоя
источник
73
Upvote за то, что не сравнивал с другим языком в своем ответе :)
Stevo
Проголосуйте за отсутствие ответа в контексте вопроса: «Если я просто хочу использовать методы из модуля в моем классе?»
Бен
57
  • Ruby requireбольше похож на «include» в других языках (таких как C). Он сообщает Ruby, что вы хотите добавить содержимое другого файла . Подобные механизмы на других языках:

  • Ruby include- это объектно-ориентированный механизм наследования, используемый для миксинов .

Существует хорошее объяснение здесь :

Простой ответ заключается в том, что требовать и включать, по сути, не связаны.

«require» аналогичен C include, что может вызвать замешательство у новичка. (Одним заметным отличием является то, что локальные файлы в требуемом файле «испаряются», когда требование выполнено.)

Ruby include - это не что иное, как C include. Оператор include «смешивает» модуль в класс. Это ограниченная форма множественного наследования . Включенный модуль буквально дарует отношения «есть» на вещи, включая ее.

Акцент добавлен.

bradheintz
источник
7

Вы когда-нибудь пробовали requireмодуль? Каковы были результаты? Просто попробуй:

MyModule = Module.new
require MyModule # see what happens

Модули не могут быть необходимы, только включены!

Борис Стиницкий
источник
Утверждение здесь не верно. Модули могут быть необходимы. И любой, выполняющий приведенный выше код, обнаружит, что он получит тот же результат ( TypeError), если слово Moduleбудет изменено на Class.
ПСР
7

Из программирования Ruby 1.9

Прежде чем мы продолжим, мы сделаем пару замечаний по поводу включения. Во-первых, это не имеет ничего общего с файлами. Программисты C используют директиву препроцессора #include для вставки содержимого одного файла в другой во время компиляции. Оператор Ruby include просто ссылается на модуль. Если этот модуль находится в отдельном файле, вы должны использовать require (или его редко используемый двоюродный брат, load), чтобы перетащить этот файл перед использованием include. Во-вторых, включение Ruby не просто копирует методы экземпляра модуля в класс. Вместо этого он делает ссылку из класса на включенный модуль. Если несколько классов включают этот модуль, они все будут указывать на одно и то же. Если вы измените определение метода в модуле, даже когда ваша программа работает,

cizixs
источник
3

Включить Когда вы включаете модуль в свой класс, как показано ниже, это выглядит так, как будто вы взяли код, определенный в модуле, и вставили его в класс, куда вы его «включили». Это позволяет «смешивать» поведение. Он используется для СУШКИ вашего кода, чтобы избежать дублирования, например, если было несколько классов, для которых в модуле требовался бы один и тот же код.

Load Метод load похож на метод require, за исключением того, что он не отслеживает, была ли загружена эта библиотека. Таким образом, можно загружать библиотеку несколько раз, а также при использовании метода load необходимо указать расширение имени файла библиотеки «.rb».

Require Метод require позволяет загружать библиотеку и предотвращает ее загрузку более одного раза. Метод require вернет false, если вы попытаетесь загрузить ту же библиотеку после первого раза. Метод require требуется использовать только в том случае, если загружаемая библиотека определена в отдельном файле, что обычно имеет место.

Вы можете предпочесть это http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/

Sanket
источник
3

Ниже приведены несколько основных различий между require и include:

Требуется:

  1. Require считывает файл из файловой системы, анализирует его, сохраняет в памяти и запускает его в заданном месте, что означает, что если вы даже что-то измените во время выполнения скрипта, это изменение не будет отражено.
  2. Нам нужен файл по имени, а не по имени модуля.
  3. Обычно используется для библиотек и расширений.

Включают:

  1. Когда вы включаете модуль в ваш класс, он ведет себя так, как будто вы взяли код, определенный в вашем модуле, и вставили его в свой класс.
  2. Мы включаем имя модуля, а не имя файла.
  3. Обычно он используется для высушивания кода и устранения дублирования в коде.
Авайс Шафкат
источник
2
require(name)

Он вернет булево значение true / false

Имя, которое передается в качестве параметра для require, ruby ​​попытается найти исходный файл с этим именем в вашем пути загрузки. Метод require вернет false, если вы попытаетесь загрузить ту же библиотеку после первого раза. Метод require требуется использовать только в том случае, если загружаемая библиотека определена в отдельном файле. Таким образом, он отслеживает, была ли эта библиотека уже загружена или нет.

include module_name

Предположим, если у вас есть несколько методов, которые вам нужны в двух разных классах. Тогда вам не нужно писать их в обоих классах. Вместо этого вы можете определить это в модуле. А затем включить этот модуль в другие классы. Он предоставляется Ruby только для обеспечения принципа СУХОЙ. Он используется, чтобы высушить ваш код, чтобы избежать дублирования

Шринивас
источник
2

Включают

Когда ты include добавляете модуль в свой класс, это как если бы вы взяли код, определенный в модуле, и вставили его в класс, куда вы его «включили». Это позволяет «смешивать» поведение. Он используется для СУШКИ вашего кода, чтобы избежать дублирования, например, если было несколько классов, для которых в модуле требовался бы один и тот же код.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

требовать

Метод require позволяет загружать библиотеку и предотвращает ее загрузку более одного раза. Метод require вернет false, если вы попытаетесь загрузить ту же библиотеку после первого раза. Метод require требуется использовать только в том случае, если загружаемая библиотека определена в отдельном файле, что обычно имеет место.

Таким образом, он отслеживает, была ли эта библиотека уже загружена или нет. Вам также не нужно указывать расширение «.rb» имени файла библиотеки. Вот пример того, как использовать require. Поместите метод require в самый верх файла «.rb»:

нагрузка

Метод load похож на метод require, за исключением того, что он не отслеживает, была ли загружена эта библиотека. Таким образом, можно загружать библиотеку несколько раз, а также при использовании метода load необходимо указать расширение имени файла библиотеки «.rb».

простираться

При использовании метода extends вместо include вы добавляете методы модуля как методы класса, а не как методы экземпляра.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type
Имран Ахмад
источник
2

'Load' - вставляет содержимое файла. (Разбор файла каждый раз, когда файл вызывается)

'Require' - вставляет проанализированный файл (файл анализируется один раз и сохраняется в памяти)

«Включить» - включает модуль в класс и может использовать методы внутри модуля в качестве метода экземпляра класса.

Extend - включает модуль в класс и может использовать методы внутри модуля как метод класса

Вайшали Венкатесан
источник