Моє запитання схоже на " Яка різниця між включенням і розширенням в Ruby? ".
Яка різниця між require
і include
в Ruby? Якщо я просто хочу використовувати методи з модуля в своєму класі, я повинен require
це чи include
це?
Моє запитання схоже на " Яка різниця між включенням і розширенням в Ruby? ".
Яка різниця між require
і include
в Ruby? Якщо я просто хочу використовувати методи з модуля в своєму класі, я повинен require
це чи include
це?
Відповіді:
Яка різниця між "включати" та "вимагати" в Ruby?
Відповідь:
Методи включати і вимагати дуже різні речі.
Метод вимагає виконувати те, що включає в себе в більшості інших мов програмування: запустіть інший файл. Він також відстежує те, що вам потрібно в минулому, і не буде вимагати одного і того ж файлу двічі. Для запуску іншого файлу без цієї додаткової функціональності можна скористатися методом завантаження.
Метод include включає всі методи з іншого модуля і включає їх у поточний модуль. Це річ на рівні мови, на відміну від речі на рівні файлу, як з вимогою. Метод include - це основний спосіб "розширити" класи іншими модулями (зазвичай їх називають сумішами). Наприклад, якщо ваш клас визначає метод "кожен", ви можете включити змішаний модуль Enumerable і він може виступати як колекція. Це може заплутати, оскільки дієслово include включається в інших мовах дуже по-різному.
Тож якщо ви просто хочете використовувати модуль, а не розширювати його чи робити суміш, тоді ви хочете використовувати require
.
Як не дивно, Рубі require
аналогічна Кассіопеяне include
, в той час як Рубі include
майже нічого , як Кассіопеяне include
.
include
у Ruby це просто спадщина. class C; include M end
складає M
надклас C
і (колишній) надклас C
надкласу M
. Я не думаю, що C include
працює через спадкування, я думаю, що це проста текстова / лексична підміна.
Якщо ви використовуєте модуль, це означає, що ви вводите всі методи у свій клас. Якщо ви 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
=> невизначений метод "сказати" для B: Class
B.new.say
=> це модуль A
C.say
=> це модуль A
C.new.say
=> невизначений метод "сказати" для C: Class
З книги "Метапрограмування" Ruby,
require()
Метод дуже схожийload()
, але це означало для різних цілей. Ви використовуєтеload()
для виконання коду, а виrequire()
імпортуєте бібліотеки.
Ruby require
більше схожий на "включити" в інших мовах (наприклад, на C). Це повідомляє Ruby, що ви хочете внести вміст іншого файлу . Подібними механізмами в інших мовах є:
Ruby include
- об'єктно-орієнтований механізм успадкування, який використовується для міксинів .
Існує гарне пояснення тут :
[Простий] відповідь полягає в тому, що вимагати і включати по суті не пов'язані між собою.
"вимагати" схожий на C include, що може спричинити плутанину новачка. (Одна помітна відмінність полягає в тому, що місцеві жителі всередині потрібного файлу "випаровуються", коли вимога виконана.)
Ruby include - це не що інше, як C include. Включити оператор "змішує" модуль у клас. Це обмежена форма багаторазового успадкування . Модуль, що входить в комплект, буквально дарує відносини "є-а" на річ, включаючи її.
Акцент додано.
Ви коли-небудь пробували require
модуль? Які були результати? Просто спробуйте:
MyModule = Module.new
require MyModule # see what happens
Модулі не потрібно вимагати, лише вони входять!
TypeError
), якщо слово Module
буде змінено на Class
.
З програмування Ruby 1.9
Ми зробимо пару пунктів щодо оператора включення, перш ніж продовжувати. По-перше, це не має нічого спільного з файлами. Програмісти C використовують директиву препроцесора під назвою #include, щоб вставити вміст одного файлу в інший під час компіляції. Оператор Ruby include просто посилається на модуль. Якщо цей модуль перебуває в окремому файлі, для використання цього файлу потрібно використовувати (або його рідше використовуваний двоюрідний брат, завантажувати), перш ніж використовувати include. По-друге, включення Ruby не просто копіює методи екземпляра модуля в клас. Натомість він робить посилання з класу на включений модуль. Якщо цей модуль включає кілька класів, всі вони вказують на одне і те ж. Якщо ви зміните визначення методу в модулі, навіть коли ваша програма працює,
Коли ви включаєте модуль у свій клас, як показано нижче, це так, як якщо б ви взяли код, визначений в модулі, і вставили його в клас, куди ви його "включили". Це дозволяє поведінку "mixin". Використовується для висушування вашого коду, щоб уникнути дублювання, наприклад, якщо в модулі було декілька класів, яким потрібен би той самий код.
Навантаження Метод завантаження майже як метод вимагає, за винятком того, що він не відслідковує, завантажена чи ні бібліотека. Таким чином, можна завантажувати бібліотеку кілька разів, а також, використовуючи метод завантаження, ви повинні вказати розширення ".rb" імені файлу бібліотеки.
Вимагати Метод вимагає завантаження бібліотеки та запобігає завантаженню не раз. Метод вимагає повернути "false", якщо ви спробуєте завантажити ту саму бібліотеку після першого разу. Метод вимагає використовувати лише в тому випадку, якщо бібліотека, яку ви завантажуєте, визначена в окремому файлі, як правило.
Ви можете віддати перевагу цьому http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/
Нижче наведено кілька основних відмінностей між потребою та включайте:
Потрібно:
Включати:
require(name)
Він поверне bolean істинним / хибним
Ім'я, яке передається як параметр до вимоги, ruby спробує знайти вихідний файл з цим ім'ям у вашому шляху завантаження. Метод вимагає повернути "false", якщо ви спробуєте завантажити ту саму бібліотеку після першого разу. Метод вимагає використовувати лише тоді, коли бібліотека, яку ви завантажуєте, визначена в окремому файлі. Отже, він відслідковує, завантажена ця бібліотека чи ні.
include module_name
Припустимо, якщо у вас є кілька методів, які вам потрібно мати у двох різних класах. Тоді не потрібно писати їх у обидва класи. Замість того, що ви можете зробити, визначте це в модулі. А потім включіть цей модуль в інші класи. Він надається Ruby тільки для забезпечення принципу DRY. Він використовується для висушування коду, щоб уникнути дублювання
Включати
Коли ви
include
модуль входите до свого класу, це як би ви взяли визначений в модулі код і вставили його в клас, куди ви його "включили". Це дозволяє поведінку "mixin". Використовується для висушування вашого коду, щоб уникнути дублювання, наприклад, якщо в модулі було декілька класів, яким потрібен би той самий код.
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
Вимагають
Метод вимагає дозволяє завантажити бібліотеку і запобігає її завантаженню не один раз. Метод вимагає повернути "false", якщо ви спробуєте завантажити ту саму бібліотеку після першого разу. Метод вимагає використовувати лише в тому випадку, якщо бібліотека, яку ви завантажуєте, визначена в окремому файлі, як правило.
Отже, він відслідковує, завантажена ця бібліотека чи ні. Також не потрібно вказувати розширення ".rb" імені файлу бібліотеки. Ось приклад того, як використовувати потрібно. Розташуйте потрібний метод у верхній частині файлу ".rb":
Навантаження
Метод завантаження майже як метод вимагає, за винятком того, що він не відстежує, завантажена чи ні ця бібліотека. Таким чином, можна завантажувати бібліотеку кілька разів, а також, використовуючи метод завантаження, ви повинні вказати розширення ".rb" імені файлу бібліотеки.
Розширити
Використовуючи метод розширення замість включати, ви додаєте методи модуля як методи класу, а не як методи екземпляра.
module Log
def class_type
"This class is of type: #{self.class}"
end
end
class TestClass
extend Log
# ...
end
tc = TestClass.class_type
"Завантажити" - вставляє вміст файлу. (Розбирає файл щоразу, коли файл викликається)
'Потрібно' - вставляє вміст, проаналізований у файлі. (Файл розбирається один раз і зберігається в пам'яті)
'Включити' - включає модуль у клас і може використовувати методи всередині модуля як метод екземпляра класу
'Extend' - включає модуль у клас і може використовувати методи всередині модуля як метод класу
require
іinclude
, а також відповідних,Module#append_features
.