Storia della questione:
Perl supporta il caricamento dinamico e statico del codice sin dall'introduzione del supporto per i moduli. A tal fine, il linguaggio fornisce tre meccanismi distinti: require, use e do. Ognuno di essi ha le proprie peculiarità, un ciclo di vita di esecuzione diverso e influenza il contesto di lavoro del programma.
Problema:
Una scelta errata del meccanismo di caricamento o una comprensione errata delle differenze tra di essi porta spesso a bug: caricamento ripetuto di moduli, problemi di ambito, errori di runtime (ad esempio, caricamento non riuscito, variabili o funzioni non inizializzate).
Soluzione:
use — collega un modulo durante la fase di compilazione. Chiama automaticamente il metodo import, se definito. Utilizzato per caricare moduli e dichiarazioni all'avvio del programma.require — carica un file o modulo durante l'esecuzione, solo una volta per programma. Ottimo per il caricamento dinamico di file in base a condizioni.do — esegue semplicemente un file come codice Perl, ogni volta che viene chiamato. Utilizzato raramente, necessario per casi speciali (ad esempio, file di configurazione).Esempio di codice:
use Some::Module; # caricamento statico if ($config{plugin}) { require "$config{plugin}.pm"; # caricamento dinamico } do 'local_config.pl'; # esegue ogni volta all'avvio
Caratteristiche chiave:
use funziona solo con package/module, chiama import, si attiva durante la compilazione.require funziona con file e moduli, si attiva a runtime.do non memorizza il modulo, ma esegue semplicemente il contenuto del file.È possibile utilizzare require per collegare una variabile e un modulo come Some::Module?
Sì, ma è necessario specificare esplicitamente il percorso del file, o trasformare il nome del modulo in un percorso:
my $mod = 'Some::Module'; $mod =~ s!::!/!g; require "$mod.pm"; # corretto
Cosa succede se do non riesce a trovare un file?
do restituisce false (undef) e registra un errore in $@ — non genera panic come use/require.
Cosa succede se si chiama require due volte sullo stesso file?
require carica il file solo la prima volta, le chiamate successive non ripeteranno il caricamento, anche se il file sorgente è stato modificato.
Nel progetto si cercava di collegare plugin al volo usando do, senza verificare lo stato restituito e confondendo con require.
Vantaggi:
Svantaggi:
Si utilizzava require per il caricamento condizionale, trasformando sempre il nome del modulo in un percorso. Controllavano $@ dopo il tentativo di caricamento.
Vantaggi:
Svantaggi: