2013-07-28 21 views
21

Non riesco a capire qual è la differenza/use case di EXPORT_OK rispetto a EXPORT.
La maggior parte delle risorse accenna qualcosa nelle linee di:export vs export_ok in perl

@Export permette di esportare le funzioni e le variabili di moduli per namespace dell'utente utilizzando il metodo standard di importazione. In questo modo, non è necessario che crei gli oggetti per i moduli per accedere ai relativi membri.
@EXPORT_OK esegue l'esportazione di simboli su richiesta per l'elenco selettivo di simboli (subroutine e variabili) del modulo.

Ma io davvero non vedo la differenza/significato qui.
Qualcuno può fornire un piccolo esempio fondamentale della differenza/utilizzo di questi 2 simboli?

+0

Non è consigliabile esportare molti simboli per impostazione predefinita, se del caso. @EXPORT sarà in genere piccolo o vuoto. @EXPORT_OK può includere molto di più. Ad esempio, Encode esporta 'encode' e' decode' di default ('@ EXPORT'), ma non' is_utf8' ('@ EXPORT_OK') – ikegami

risposta

15

Dal fine Exporter manual:

  • use YourModule;
    Questo importa tutti i simboli nomemodulo di @EXPORT nel namespace del utilizzo dichiarazione.
  • use YourModule();
    Ciò fa sì che perl carichi il modulo ma non importi alcun simbolo.
  • use YourModule qw(...);
    Questo importa solo i simboli elencati dal chiamante nel proprio spazio dei nomi. Tutti i simboli elencati devono essere nel tuo @EXPORT o @EXPORT_OK, altrimenti si verifica un errore. Le funzionalità di esportazione avanzate di Exporter sono accessibili in questo modo, ma con voci di lista che sono sintatticamente distinte dai nomi dei simboli.

Quindi, se si utilizza @EXPORT e qualcuno fa il solito use YourModule;, allora hai appena inquinato il loro spazio dei nomi con tutto in @EXPORT. Ma se usi @EXPORT_OK, loro devono chiedere specificamente cose da importare in modo che la persona che usa il tuo modulo abbia il controllo su cosa succede al loro spazio dei nomi.

la differenza è davvero una questione di chi controlla cosa entra nel namespace use del r: se si utilizza @EXPORT allora il modulo essendo use d fa, se si utilizza @EXPORT_OK quindi il codice a fare l'importazione controlla il proprio spazio dei nomi.

Ovviamente, puoi sempre dire use Whatever(); per impedire ai moduli maleducati di inquinare il tuo spazio dei nomi, ma questo è brutto e non dovresti avere a che fare con codice maleducato che vuole scarabocchiare tutto il tuo spazio dei nomi.

+0

Quindi' usa YourModule qw (ab); 'e' @EXPORT qw (ab), 'non ha senso? In caso contrario, non vedo ancora perché abbiamo bisogno di '@ EXPORT_OK' – Jim

+3

@Jim' il nostro @ EXPORT' contiene i simboli esportati di default (cioè, con 'use YourModule;'). Fare ciò è considerato una * cattiva pratica *. '@ EXPORT_OK' contiene un elenco di tutti i simboli che * possono * essere esportati su richiesta esplicita. – amon

35

Diciamo che ho un pacchetto MyPackage che utilizza @EXPORT.

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

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

Ora, quando uso MyPackage nel mio codice,

#this is myscript.pl 
use MyPackage; 

do_awesome_thing(); #works 

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

do_awesome_thing ottiene esportati automaticamente al mio codice da MyPackage, senza di me dover dire "dare a questo a me". be_awesome non viene esportato (e non verrà esportato con @EXPORT_OK, sto solo mostrando quella parte per chiarire cosa ci "esporta").

D'altra parte, se ho un pacchetto MyOtherPackage che utilizza @EXPORT_OK,

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

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

e quindi provare

#this is mynewscript.pl 
use MyOtherPackage; 

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

la linea chiamando direttamente do_awesome_thing non funzionerà. Questo perché mettere qualcosa in @EXPORT_OK dice "dai ai miei utenti solo se lo chiedono". Poiché abbiamo appena detto use MyOtherPackage senza chiedere esplicitamente che do_awesome_thing venga importato qui, non viene importato ed è accessibile solo specificando il nome del pacchetto.

Il modo in cui si richiede do_awesome_thing da importare è use MyOtherPackage qw(do_awesome_thing) nella seconda riga di mynewscript.pl precedente. Questo dice importare quel modulo e rendere disponibile do_awesome_thing direttamente. Dopodiché, la quarta riga in mynewscript.pl inizierà a funzionare.

Si noti che l'utente può specificare anche use MyPackage qw(do_awesome_thing) con il primo pacchetto, e in tal caso, qualsiasi altro contenuto nell'elenco @EXPORT non verrà esportato, sarà solo do_awesome_thing. Pertanto, ad eccezione del caso predefinito use PackageName;, @EXPORT e @EXPORT_OK si comportano in modo simile. Nel caso predefinito, qualsiasi elemento di @EXPORT viene automaticamente inserito nello script dell'utente, mentre @EXPORT_OK è più educato e non esporta nulla.

+4

* Con @EXPORT, hai solo due scelte * ... errate; semplicemente sbagliato '@ EXPORT' e' @ EXPORT_OK' funzionano principalmente allo stesso modo: in entrambi i casi l'utente può specificare l'elenco di nomi che desidera importare. Essi * solo * differiscono in ciò che accade quando l'utente fornisce * nessun elenco di nomi da importare * - in quella situazione, le cose su '@ EXPORT' vengono esportate, e le cose su' @ EXPORT_OK' non lo sono. – tobyink

+1

@tobyink Grazie, non ho lavorato molto con EXPORT quindi non lo sapevo, ora ho cambiato quella parte. Mentre ho cercato su Google per confermare ciò, mi sono imbattuto in questo libro di O'Reilly (http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm) che sembra commettere lo stesso errore che ho fatto: "Se il modulo usa EXPORT invece di EXPORT_OK, l'utente ottiene tutti i simboli esportati, indipendentemente dal fatto che siano stati menzionati nell'elenco di importazione o meno. " Ma ho testato il comportamento e confermato che avevi ragione e il libro (apparentemente) sbagliato. – sundar