2013-07-28 11 views
21

Nie mogę zrozumieć, jaka jest różnica/przypadek użycia EXPORT_OK vs EXPORT.
Większość zasobów wspomina coś w linii:eksport vs export_ok w perlu

@Export pozwala eksportować funkcje i zmienne modułów do nazw użytkownika przy użyciu standardowej metody importu. W ten sposób nie musimy tworzyć obiektów dla modułów, aby uzyskać dostęp do ich członków.
@EXPORT_OK eksportuje symbole na żądanie dla listy selektywnej symboli (podprogramów i zmiennych) modułu.

Ale ja naprawdę nie widzę różnicy/znaczenia tutaj.
Czy ktoś może podać mały fundamentalny przykład różnicy/użycia tych 2 symboli?

+0

Nie należy eksportować wielu symboli domyślnie, jeśli w ogóle. @EXPORT będzie zazwyczaj mały lub pusty. @EXPORT_OK może zawierać znacznie więcej. Na przykład kodowanie eksportuje domyślnie 'kodowanie' i' dekodowanie '('@ EXPORT'), ale nie' is_utf8' ('@ EXPORT_OK') – ikegami

Odpowiedz

15

Z fine Exporter manual:

  • use YourModule;
    ten importuje wszystkie symbole z YourModule na @EXPORT do przestrzeni nazw użytku oświadczeniu.
  • use YourModule();
    Powoduje to, że perl ładuje twój moduł, ale nie importuje żadnych symboli.
  • use YourModule qw(...);
    Spowoduje to zaimportowanie tylko symboli wymienionych przez wywołującego w ich przestrzeni nazw. Wszystkie wymienione symbole muszą znajdować się w twoim @EXPORT lub @EXPORT_OK, w przeciwnym razie wystąpi błąd. Zaawansowane funkcje eksportu programu Exporter są dostępne w ten sposób, ale z wpisami listy, które są syntaktycznie różne od nazw symboli.

Tak więc, jeśli używasz @EXPORT i ktoś robi zwykły use YourModule;, to właśnie zanieczyszczona ich nazw ze wszystkim w @EXPORT. Ale jeśli używasz @EXPORT_OK, muszą one konkretnie poprosić o zaimportowanie rzeczy, aby osoba korzystająca z modułu miała kontrolę nad tym, co dzieje się z ich obszarem nazw.

Różnica jest naprawdę kwestia kto kontroluje to, co dostaje się do przestrzeni nazw use R: jeśli używasz @EXPORT następnie moduł jest use d robi, jeśli używasz @EXPORT_OK następnie kod robi import kontroluje własną przestrzeń nazw.

Oczywiście zawsze możesz powiedzieć use Whatever();, aby nieuprawnione moduły nie zanieczyszczały przestrzeni nazw, ale to jest brzydkie i nie powinieneś kłaść się wokół grubiańskiego kodu, który chce przeszukać cały obszar nazw.

+0

Tak więc" używaj swojego modułu qw (ab); "i" @EXPORT qw (ab); 'jest bez znaczenia? Jeśli nie, to nadal nie rozumiem, dlaczego potrzebujemy '@ EXPORT_OK' – Jim

+3

@Jim' nasz @ EXPORT' zawiera symbole, które eksportujesz domyślnie (to znaczy, używając 'use YourModule;'). Wykonanie tego jest uważane za * kiepską praktykę *. '@ EXPORT_OK' zawiera listę wszystkich symboli, które * można * wyeksportować na wyraźne żądanie. – amon

35

Załóżmy, że mam pakiet MyPackage, który używa @EXPORT.

#this is MyPackage.pm 
package MyPackage; 
@EXPORT = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

Teraz, gdy używam MyPackage w moim kodu,

#this is myscript.pl 
use MyPackage; 

do_awesome_thing(); #works 

be_awesome(); #doesn't work 
MyPackage::be_awesome(); #works 

do_awesome_thing zostanie automatycznie eksportowane do mojego kodu z MyPackage, bez konieczności mi powiedzieć "daj mi to". be_awesome nie jest eksportowany (i nie będzie eksportowany z @EXPORT_OK, po prostu pokazuję tę część, aby wyjaśnić, co daje nam "eksportowanie").

Z drugiej strony, jeśli mam pakiet MyOtherPackage który używa @EXPORT_OK,

#this is MyOtherPackage.pm 
package MyOtherPackage; 
@EXPORT_OK = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

a następnie spróbuj

#this is mynewscript.pl 
use MyOtherPackage; 

do_awesome_thing(); #doesn't work 
MyOtherPackage::do_awesome_thing(); #works, as always 

linia nazywając do_awesome_thing bezpośrednio nie będzie działać. Dzieje się tak dlatego, że umieszczenie czegoś w @EXPORT_OK mówi "przekaż to moim użytkownikom tylko wtedy, gdy o to poprosią". Odkąd właśnie powiedzieliśmy, że use MyOtherPackage nie wymaga jawnego importowania tutaj do_awesome_thing, nie jest on importowany i jest dostępny tylko po podaniu nazwy pakietu.

Sposób, w jaki należy poprosić o zaimportowanie do_awesome_thing, to use MyOtherPackage qw(do_awesome_thing) w drugiej linii mynewscript.pl powyżej. Oznacza to, że należy zaimportować ten moduł i udostępnić do_awesome_thing bezpośrednio. Następnie czwarta linia w powyższej mynewscript.pl zacznie działać.

Należy pamiętać, że użytkownik może określić use MyPackage qw(do_awesome_thing) również z pierwszym pakietem. W takim przypadku wszystkie elementy listy @EXPORT nie zostaną wyeksportowane, a jedynie do_awesome_thing. Tak więc, z wyjątkiem domyślnego przypadku use PackageName;, @EXPORT i @EXPORT_OK zachowują się podobnie. W domyślnym przypadku cokolwiek w @EXPORT zostaje automatycznie wrzucone do skryptu użytkownika, podczas gdy @EXPORT_OK jest bardziej uprzejme i nie eksportuje niczego.

+4

* Z @EXPORT masz tylko dwie opcje * ... źle; po prostu źle. '@ EXPORT' i' @ EXPORT_OK' działają w większości tak samo: w obu przypadkach użytkownik może określić listę nazw, które chce zaimportować. One * only * różnią się tym, co dzieje się, gdy użytkownik podaje * brak listy nazw do zaimportowania * - w takiej sytuacji rzeczy na '@ EXPORT' są eksportowane, a rzeczy na' @ EXPORT_OK' nie są. – tobyink

+1

@tobyink Dzięki, nie pracowaliście z EXPORT dużo, więc nie wiedzieliśmy, że zmieniłem tę część teraz. Podczas Googling, aby to potwierdzić, natknąłem się na tę książkę O'Reilly (http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm), która wydaje się robić ten sam błąd co ja: "Jeśli moduł używa EXPORT zamiast EXPORT_OK, użytkownik otrzymuje wszystkie wyeksportowane symbole, niezależnie od tego, czy zostały one wymienione na liście importu, czy nie. " Ale testowałem zachowanie i potwierdziłem, że masz rację, a książka (podobno) jest nieprawidłowa. – sundar