La versione breve è che si desiderava un modulo, ma si è finito con quello che this chiama una libreria. Questi non sono buoni perché inquinano lo spazio dei nomi del chiamante (che può causare molti problemi). Ma ancora più importante, caricarli usando require
o use
(come opposto a do
) è buggato.
Se fosse stato scritto correttamente come modulo, il tuo esempio non funzionerebbe. L'esportatore è la soluzione a questo problema.
Entriamo nei dettagli.
Come ho già detto, c'è un problema con il modulo. Come hai notato, a volte funziona nonostante l'errore.
$ cat Buggy.pm
sub test { "ok!" }
1;
$ perl -e'use Buggy; CORE::say(test());'
ok!
Ma questo è solo perché il tuo esempio è troppo semplice. Aggiungiamo al modulo un modulo [1] correttamente scritto.
$ cat Buggy.pm
sub test { "ok!" }
1;
$ cat Other.pm
package Other;
use Buggy;
1;
$ perl -e'use Other; use Buggy; CORE::say(test());'
Undefined subroutine &main::test called at -e line 1.
Il bug nel modulo è che non ha una direttiva package
. I moduli caricati utilizzando use
e require
devono sempre utilizzare una direttiva package
. Ma non appena lo aggiungi, il tuo modulo smette di funzionare.
$ cat NotBuggy.pm
package NotBuggy;
sub test { "ok!" }
1;
$ perl -e'use NotBuggy; CORE::say(test());'
Undefined subroutine &main::test called at -e line 1.
L'esportatore è utilizzato per risolvere questo problema.
$ cat Final.pm
package Final;
use Exporter qw(import);
our @EXPORT = qw(test);
sub test { "ok!" }
1;
$ perl -e'use Final; CORE::say(test());'
ok!
- Beh, non proprio. Se è stato scritto correttamente, dovrebbe includere
use strict; use warnings 'all';
. Includilo sempre! È stato omesso qui per mantenere le cose visivamente semplici.
Grazie. Vedo la differenza Ma una "biblioteca" è davvero ciò che volevo. L'unica ragione per cui potrei volere un modulo è se non ci fosse un altro modo per ottenere una libreria. È bizzarro dire che se lo avessi scritto correttamente non avrebbe funzionato. LOL. Suppongo che l'inquinamento sia nella mente di chi guarda. Non considero l'accesso alle mie subroutine come inquinamento. La complessità inutile è l'inquinamento. – user1067305
L'inquinamento non è la presenza di cose ricercate; è la presenza di cose indesiderate.Il problema è che hai accesso non solo ai sottotitoli che vuoi esportare, ma anche ai sottotitoli interni al tuo modulo. È l'equivalente sub delle variabili globali. La programmazione è tutta una questione di limiti, esattamente l'opposto di ciò che hai detto è buono. Rendere tutto globale rende le cose più difficili da leggere, eseguire il debug, mantenere, ecc. Ecc. No, questo non è un problema di stile. La totalità dei programmatori Perl ha smesso di usare queste "librerie" quando Perl ha aggiunto il supporto per lo spazio dei nomi 20 anni fa. – ikegami
Per farla breve, compartimentare il codice richiede un piccolo codice in più, ma rende il programma molto * meno * complesso. – ikegami