Jaka jest różnica między włączeniem a wymaganiem w Ruby?


Odpowiedzi:


543

Jaka jest różnica między „włącz” i „wymagaj” w Ruby?

Odpowiedź:

Metody „włącz i wymagaj” robią bardzo różne rzeczy.

Metoda wymaga robi to, co obejmuje w większości innych języków programowania: uruchom inny plik. Śledzi również to, czego wymagałeś w przeszłości i nie będzie wymagał dwa razy tego samego pliku. Aby uruchomić inny plik bez tej dodatkowej funkcjonalności, możesz użyć metody ładowania.

Metoda include bierze wszystkie metody z innego modułu i włącza je do bieżącego modułu. Jest to rzecz na poziomie języka, w przeciwieństwie do rzeczy na poziomie pliku, jak w przypadku wymagania. Metoda dołączania jest podstawowym sposobem „rozszerzania” klas o inne moduły (zwykle nazywane wtyczkami). Na przykład, jeśli twoja klasa definiuje metodę „każdy”, możesz dołączyć moduł mieszania Enumerable i może on działać jako kolekcja. Może to być mylące, ponieważ czasownik dołączający jest używany w różny sposób w innych językach.

Źródło

Więc jeśli chcesz po prostu użyć modułu, zamiast go rozszerzyć lub zrobić wtyczkę, to zechcesz użyć require.

Co dziwne, Ruby requirejest analogiczna do C użytkownika include, podczas gdy Ruby includema prawie nic jak C użytkownika include.


45
W rzeczywistości C włącza, nie ładuje pliku tak, jak wymagają tego, ale zamiast tego zastępuje linię #include, zawartością pliku. Dołączone pliki nie muszą być „nagłówkiem”, a #include nie musi znajdować się na początku pliku, ale może znajdować się w dowolnym miejscu, na przykład w klasie lub nawet w definicji metody. Oznacza to, że możesz robić miksy w C ++, pisząc niektóre metody w pliku i dołączając go do kodu klasy, dokładnie tak, jak zrobiłbyś to w Rubim. Więc nie są tak daleko, chociaż w rzeczywistości nie jest to powszechna praktyka u C.
mb14

13
Ta odpowiedź może przynieść korzyści poprzez podanie przykładów.
Travis Bear,

12
Komentarz mb14 implikuje to, ale należy stwierdzić wprost: w przeciwieństwie do tego, co mówi odpowiedź, polecenie wymaga nie „uruchamia” pliku, ale ładuje go tak, jakby był częścią pliku zawierającego. Może się to wydawać semantycznym nitpikowaniem, ale w rzeczywistości jest to dość ważna różnica.
Lonny Eachus

Świetne wyjaśnienie. Dzięki, że wróciłeś do sedna z ostatnim stwierdzeniem: „Co dziwne, wymaganie Ruby jest analogiczne do włączenia C, podczas gdy włączenie Ruby prawie nie przypomina takiego włączenia C”.
ArtSabintsev

1
@GregSchmit: includew Ruby jest po prostu dziedziczenie. class C; include M endtworzy Mnadklasę Ci (dawną) nadklasę Cnadklasy z M. Nie sądzę, że C includedziała poprzez dziedziczenie, myślę, że jest to proste podstawienie tekstowe / leksykalne.
Jörg W Mittag

100

Jeśli używasz modułu, oznacza to, że wprowadzasz wszystkie metody do swojej klasy. Jeśli jesteś extendklasą z modułem, oznacza to, że „wprowadzasz” metody modułu jako metody klasowe . Jeśli jesteś includeklasą z modułem, oznacza to, że „wprowadzasz” metody modułu jako metody instancji .

DAWNY:

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

 class B
   include A
 end

 class C
   extend A
 end

B.say => niezdefiniowana metoda „powiedzieć” dla B: Klasa

B.new.say => to jest moduł A.

C.say => to jest moduł A.

C.new.say => niezdefiniowana metoda „say” dla C: Class


23
Myślę, że to nie odpowiada na pytanie, ale właśnie tego szukałem =)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
To faktycznie nie odpowiedzieć na pytanie, jakie są różnice requirei includesą.

94

Z książki Ruby Metaprogramming,

require()Metoda jest bardzo podobny do load(), ale jest przeznaczona do innych celów. Używasz go load()do wykonania kodu i require()importujesz biblioteki.


73
Głosuj za brak porównania z innym językiem w swojej odpowiedzi :)
Stevo

Głosuj w dół za nieudzielenie odpowiedzi w kontekście pytania: „Czy chcę po prostu użyć metod z modułu w mojej klasie?”
benc

57
  • Ruby requirebardziej przypomina „włącz” w innych językach (takich jak C). Mówi Ruby, że chcesz wprowadzić zawartość innego pliku . Podobne mechanizmy w innych językach to:

  • Ruby includejest zorientowanym obiektowo mechanizmem dziedziczenia stosowanym dla mixin .

Istnieje dobre wytłumaczenie tutaj :

[Prosta] odpowiedź brzmi, że wymagania i uwzględnienia są zasadniczo niezwiązane.

"wymagać" jest podobne do włączenia C, co może powodować zamieszanie początkujących. (Jedną zauważalną różnicą jest to, że lokale wewnątrz wymaganego pliku „wyparowują”, gdy jest to wymagane).

Ruby to jest nic innego jak C należą. Instrukcja include „wtapia” moduł w klasę. Jest to ograniczona forma wielokrotnego dziedziczenia . Dołączony moduł dosłownie nadaje relację „to-a” dla rzeczy, w tym również.

Podkreślenie dodane.


7

Czy próbowałeś kiedyś requiremodułu? Jakie były wyniki? Spróbuj:

MyModule = Module.new
require MyModule # see what happens

Moduły nie mogą być wymagane, tylko zawarte!


Twierdzenie tutaj jest nieprawidłowe. Moduły mogą być wymagane. I każdy, kto uruchomi powyższy kod, zauważy, że otrzyma ten sam wynik ( TypeError), jeśli słowo Modulezostanie zmienione na Class.
pjd

7

Od programowania Ruby 1.9

Zanim przejdziemy dalej, przedstawimy kilka uwag na temat instrukcji include. Po pierwsze, nie ma to nic wspólnego z plikami. Programiści C używają dyrektywy preprocesora o nazwie #include, aby wstawiać zawartość jednego pliku do drugiego podczas kompilacji. Instrukcja włączenia Ruby po prostu odnosi się do modułu. Jeśli ten moduł znajduje się w osobnym pliku, musisz użyć wymaganego (lub jego rzadziej używanego kuzyna, load), aby przeciągnąć ten plik przed użyciem opcji include. Po drugie, dołączenie Ruby nie kopiuje po prostu metod instancji modułu do klasy. Zamiast tego robi odwołanie z klasy do dołączonego modułu. Jeśli wiele klas zawiera ten moduł, wszystkie będą wskazywać na to samo. Jeśli zmienisz definicję metody w module, nawet podczas działania programu,


3

Uwzględnij Kiedy dołączasz moduł do swojej klasy, jak pokazano poniżej, to tak, jakbyś wziął kod zdefiniowany w module i wstawił go do klasy, gdzie „dołączasz” go. Umożliwia zachowanie „mieszania”. Służy do OSUSZANIA kodu, aby uniknąć powielania, na przykład, jeśli istnieje wiele klas, które potrzebują tego samego kodu w module.

Załaduj Metoda ładowania jest prawie podobna do metody wymagającej, ale nie śledzi, czy biblioteka została załadowana. Możliwe jest więc wielokrotne ładowanie biblioteki, a także przy użyciu metody ładowania należy podać rozszerzenie „.rb” nazwy pliku biblioteki.

Wymagaj Metoda wymaga pozwala załadować bibliotekę i zapobiega jej ładowaniu więcej niż jeden raz. Wymagana metoda zwróci „fałsz”, jeśli spróbujesz załadować tę samą bibliotekę po raz pierwszy. Metodę wymaganą należy zastosować tylko wtedy, gdy ładowana biblioteka jest zdefiniowana w osobnym pliku, co zwykle ma miejsce.

Możesz preferować ten http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/


3

Poniżej kilka podstawowych różnic między wymaganiem i obejmują:

Wymagać:

  1. Wymagaj odczytuje plik z systemu plików, analizuje go, zapisuje w pamięci i uruchamia w określonym miejscu, co oznacza, że ​​nawet jeśli cokolwiek zmienisz podczas działania skryptu, zmiana ta nie zostanie odzwierciedlona.
  2. Wymagamy pliku według nazwy, a nie nazwy modułu.
  3. Zwykle jest używany do bibliotek i rozszerzeń.

Zawierać:

  1. Gdy dołączasz moduł do swojej klasy, zachowuje się on tak, jakbyś wziął kod zdefiniowany w module i wstawił go do klasy.
  2. Podajemy nazwę modułu, a nie nazwę pliku.
  3. Zwykle służy do wysuszenia kodu i usunięcia duplikacji w kodzie.

2
require(name)

Zwróci bolean true / false

Nazwa, która jest przekazywana jako parametr do wymaganej, ruby ​​spróbuje znaleźć plik źródłowy o tej nazwie w ścieżce ładowania. Wymagana metoda zwróci „fałsz”, jeśli spróbujesz załadować tę samą bibliotekę po raz pierwszy. Wymaganej metody należy użyć tylko wtedy, gdy ładowana biblioteka jest zdefiniowana w osobnym pliku. Śledzi więc, czy ta biblioteka została już załadowana, czy nie.

include module_name

Załóżmy, że masz jakieś metody, które musisz mieć w dwóch różnych klasach. Nie musisz pisać ich w obu klasach. Zamiast tego możesz to zdefiniować w module. A następnie dołącz ten moduł do innych klas. Jest on zapewniany przez Ruby tylko w celu zapewnienia zasady DRY. Służy do OSUSZANIA kodu, aby uniknąć powielania


2

Zawierać

Kiedy wpadasz includemoduł do swojej klasy, to tak, jakbyś wziął kod zdefiniowany w module i wstawił go do klasy, gdzie „dołączasz” go. Umożliwia zachowanie „mieszania”. Służy do OSUSZANIA kodu, aby uniknąć powielania, na przykład, jeśli istnieje wiele klas, które potrzebują tego samego kodu w module.

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

Wymagać

Metoda wymaga pozwala załadować bibliotekę i zapobiega jej ładowaniu więcej niż jeden raz. Wymagana metoda zwróci „fałsz”, jeśli spróbujesz załadować tę samą bibliotekę po raz pierwszy. Metodę wymaganą należy zastosować tylko wtedy, gdy ładowana biblioteka jest zdefiniowana w osobnym pliku, co zwykle ma miejsce.

Śledzi więc, czy ta biblioteka została już załadowana, czy nie. Nie musisz także określać rozszerzenia „.rb” nazwy pliku biblioteki. Oto przykład, w jaki sposób używać wymaga. Umieść wymaganą metodę na samej górze pliku „.rb”:

Załaduj

Metoda ładowania jest prawie podobna do metody wymagającej, ale nie śledzi, czy biblioteka została załadowana. Możliwe jest więc wielokrotne ładowanie biblioteki, a także przy użyciu metody ładowania należy podać rozszerzenie „.rb” nazwy pliku biblioteki.

Poszerzać

Gdy używasz metody rozszerzania zamiast dołączania, dodajesz metody modułu jako metody klas zamiast metod instancji.

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

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type

2

„Ładuj” - wstawia zawartość pliku (parsuj plik za każdym razem, gdy plik jest wywoływany)

„Wymagaj” - wstawia przeanalizowany plik. (Plik przeanalizowano raz i zapisano w pamięci)

„Uwzględnij” - włącza moduł do klasy i może wykorzystywać metody wewnątrz modułu jako metodę instancji klasy

„Rozszerz” - włącza moduł do klasy i może wykorzystywać metody wewnątrz modułu jako metody klasy

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.