2010-02-01 13 views
47

Another question dało mi do myślenia na temat różnych metod ponownego wykorzystania kodu: use vs. require vs. doW języku Perl, czy lepiej użyć modułu niż wymagać pliku?

widzę wiele stanowisk tutaj gdzie centra zapytania wokół wykorzystania require załadować i wykonać kod. To wydaje mi się być oczywistą złą praktyką, ale nie znalazłem żadnych dobrych zasobów w kwestii, na którą mogę wskazać ludzi.

perlfaq8 pokrywa różnicę między use i require, ale nie oferuje żadnych porad w odniesieniu do preferencji (stan na 5.10 - w 5.8.8 there is a quick bit of advice in favor of use).

Ten temat wydaje się cierpieć z powodu braku dyskusji. Mam kilka pytań, które chciałbym omówić:

  1. Jaka jest preferowana metoda ponownego użycia kodu w Perlu?
    • use ModuleName;
    • require ModuleName;
    • require 'file.pl';
    • do 'file.pl';
  2. Jaka jest różnica między require ModuleName i require "file.pl"?
  3. Czy warto używać require "file.pl"? Dlaczego lub dlaczego nie?
+0

Czy chodziło ci o 'require Module' lub może' do "file" 'zamiast' require "file" '? –

+0

@Michael, 'require" plik "' faktycznie używa 'do" pliku '' do przetwarzania jego arugment, ale będzie działać tylko na danym pliku jeden raz. – daotoad

+0

@daotoad: Nie o to pytałem. Zazwyczaj 'do' jest używane dla plików * .pl, podczas gdy' require' jest używane dla plików * .pm. Oczywiście rozszerzenie pliku nie ma znaczenia, ale zgodnie z konwencją * .pl przez długi czas nie oznaczało "biblioteki perla". Próbowałem wyjaśnić, czy odnosiłeś się do starego użycia, czy też pytanie powinno zostać zmodyfikowane, aby odzwierciedlić trzy sposoby ładowania kodu zewnętrznego ('use',' require' i 'do'). W sensie bardziej sensownym (do mnie) byłoby uwzględnienie wszystkich trzech form w dyskusji. –

Odpowiedz

63

Standardową praktyką jest zwykle używanie use, require i do.

do 'file' wykona file jako skrypt Perla. To prawie jak wywoływanie eval na zawartości pliku; jeśli będziesz ten sam plik kilka razy (np. w pętli), będzie on analizowany i analizowany za każdym razem, co jest mało prawdopodobne, aby było to, co chcesz. Różnica między do ipolega na tym, że do nie widzi zmiennych leksykalnych w otaczającym zakresie, co czyni go bezpieczniejszym. do jest czasami przydatny do prostych zadań, takich jak przetwarzanie pliku konfiguracyjnego zapisanego w postaci kodu Perla.

require 'file' jest jak do 'file' z tym wyjątkiem, że analizuje tylko jeden określony plik jeden raz i zgłosi wyjątek, jeśli coś pójdzie nie tak. (np. plik nie może zostać znaleziony, zawiera błąd składni itp.) Automatyczne sprawdzanie błędów sprawia, że ​​jest on dobrym zamiennikiem dla do 'file', ale nadal nadaje się tylko do tych samych prostych zastosowań.

Formularze do 'file' i require 'file' przenoszą się z poprzednich dni, kiedy rozszerzenie pliku * .pl oznaczało "Biblioteka Perla". Nowoczesny sposób ponownego wykorzystania kodu w Perlu polega na uporządkowaniu go w moduły. Nazwanie czegoś "modułem" zamiast "biblioteki" jest po prostu semantyką, ale słowa oznaczają wyraźnie różne rzeczy w kulturze Perla. Biblioteka to tylko zbiór podprogramów; moduł zapewnia przestrzeń nazw, dzięki czemu jest bardziej odpowiedni do ponownego użycia.

use Module to normalny sposób użycia kodu z modułu. Zauważ, że Module to nazwa pakietu jako bareword, a nie cytowany ciąg zawierający nazwę pliku. Perl obsługuje tłumaczenie z nazwy pakietu na nazwę pliku. use instrukcje występują w czasie kompilacji i generują wyjątek, jeśli się nie powiedzie. Oznacza to, że jeśli moduł, od którego twój kod jest zależny, nie jest dostępny lub nie załaduje się, błąd będzie widoczny natychmiast. Dodatkowo, use automatycznie wywołuje metodę import() modułu, jeśli ma taką, która może zaoszczędzić ci trochę pisania.

require Module jest podobny do use Module, z tym że dzieje się w czasie wykonywania i nie wywołuje automatycznie metody modułu import(). Zwykle chcesz użyć use, aby wcześnie i przewidywalnie przestać działać, ale czasami lepiej jest require. Na przykład: require może być użyty do opóźnienia ładowania dużych modułów, które są tylko sporadycznie wymagane lub do opcjonalnego modułu. (użyj modułu, jeśli jest dostępny, ale cofnij się do czegoś innego lub zmniejsz funkcjonalność, jeśli tak nie jest).

Ściśle mówiąc, jedyną różnicą między require Module a require 'file' jest to, że pierwsza forma uruchamia automatyczne tłumaczenie z paczki o nazwie takiej jak Foo::Bar do nazwy pliku, takiej jak Foo/Bar.pm, podczas gdy druga forma oczekuje nazwy pliku. Zgodnie z konwencją pierwsza forma jest używana do ładowania modułów, podczas gdy druga forma służy do ładowania bibliotek.

5

Jest głównym preferencji za korzystanie use, ponieważ zdarza się we wcześniejszym stanie BEGIN {} podczas kompilacji, a błędy wydają się być propagowane do użytkownika w bardziej odpowiednim czasie. Wywołuje również funkcję sub import {}, która daje kontrolę wywołującą nad procesem importowania. To jest coś, co jest mocno wykorzystywane. Możesz uzyskać ten sam efekt, wywołując konkretną przestrzeń nazw import, ale to wymaga znajomości nazwy przestrzeni nazw i pliku oraz zakodowania wywołania podprogramu ... co jest znacznie więcej pracy. Odwrotnie, use, po prostu wymaga, abyś znał przestrzeń nazw, a następnie wymaga pliku z pasującą przestrzenią nazw - w ten sposób czyniąc łącze pomiędzy przestrzeniami nazw i plikami mniej świadomymi dla użytkownika.

Przeczytaj perldoc -f use i perldoc -f require, aby uzyskać więcej informacji. Na perldoc -f use: use jest taki sam jak BEGIN { require Module; Module->import(LIST); } Co jest po prostu o wiele bardziej brzydkie.

4

Główna różnica dotyczy importu/eksportu. use korzystne jest, gdy jesteś przy wykorzystaniu modułu, ponieważ pozwala na określenie, które procedury chcesz zaimportować do nazw:

use MyModule qw(foo bar baz); # allows foo(), bar() and baz() to be used 

use MyModule qw(); # Requires explicit naming (e.g. MyModule::foo). 

use daje również biegnie import() procedurę modułu, który jest często używany do ustawiania moduł do góry.

Aby uzyskać więcej informacji, zobacz perldoc dla use.

+0

W rzeczywistości są jednym w tym samym. W twoim przykładzie 'MyModule :: import()' akceptuje 'qw (foo bar baz)' i robi sam eksport. Jest to ten sam obiekt, 'Exporter' i' Sub :: Exporter' po prostu generują 'import()'. –

2

Do modułu zostanie dodany moduł podczas kompilacji, co zwiększy prędkość, ale zużyje więcej pamięci, podczas gdy użycie modułu require będzie uwzględniać podczas działania. Wymaganie modułu bez użycia w razie potrzeby importu zużywa mniej pamięci, ale zmniejsza prędkość.

Powiązane problemy