perlsub - Online nel cloud

Questo è il comando perlsub che può essere eseguito nel provider di hosting gratuito OnWorks utilizzando una delle nostre molteplici workstation online gratuite come Ubuntu Online, Fedora Online, emulatore online Windows o emulatore online MAC OS

PROGRAMMA:

NOME


perlsub - subroutine Perl

SINOSSI


Per dichiarare i sottoprogrammi:

sotto NOME; # Una dichiarazione "in avanti".
sub NOME(PROTO); # idem, ma con prototipi
sub NOME : ATTRS; # con attributi
sub NAME(PROTO) : ATTRS; # con attributi e prototipi

sub BLOCCO NOME # Una dichiarazione e una definizione.
sub NAME(PROTO) BLOCK # idem, ma con prototipi
sub NAME(SIG) BLOCK # con una firma invece
sub NAME : ATTRS BLOCK # con attributi
sub NAME(PROTO) : ATTRS BLOCK # con prototipi e attributi
sub NAME(SIG): ATTRS BLOCK # con una firma e attributi

Per definire una subroutine anonima in fase di esecuzione:

$subref = sottoBLOCCO; # nessun protocollo
$subref = sub (PROTO) BLOCCO; # con proto
$subref = sub (SIG) BLOCCO; # con firma
$subref = sub: BLOCCO ATTR; # con attributi
$subref = sub (PROTO): ATTRS BLOCK; # con proto e attributi
$subref = sub (SIG): ATTRS BLOCK; # con firma e attributi

Per importare le subroutine:

usa MODULO qw(NOME1 NOME2 NOME3);

Per chiamare i sottoprogrammi:

LISTA DI NOMI); # & è facoltativo tra parentesi.
LISTA DI NOMI; # Parentesi facoltative se predichiarate/importate.
&LISTA DI NOMI); # Eludere i prototipi.
&NOME; # Rende @_ corrente visibile alla subroutine richiamata.

DESCRIZIONE


Come molti linguaggi, Perl fornisce subroutine definite dall'utente. Questi possono essere localizzati
ovunque nel programma principale, caricato da altri file tramite "do", "require" o "use"
parole chiave o generate al volo utilizzando subroutine "eval" o anonime. puoi anche
chiamare una funzione indirettamente utilizzando una variabile contenente il suo nome o un riferimento CODE.

Il modello Perl per la chiamata di funzione e i valori restituiti è semplice: tutte le funzioni vengono passate come
parametri un unico elenco piatto di scalari e tutte le funzioni ritornano allo stesso modo alla loro
chiamante un unico elenco piatto di scalari. Qualsiasi array o hash in questi chiama e ritorna
le liste collasseranno, perdendo la loro identità, ma puoi sempre usare il pass-by-reference
invece per evitare questo. Sia le liste di chiamata che quelle di ritorno possono contenere tanti o pochi scalari
elementi come desideri. (Spesso viene chiamata una funzione senza un'istruzione return esplicita
una subroutine, ma non c'è davvero alcuna differenza dal punto di vista di Perl.)

Tutti gli argomenti passati vengono visualizzati nell'array @_. (Potrebbero anche apparire in lessicale
variabili introdotte da una firma; vedi "Firme" di seguito.) Pertanto, se hai chiamato a
funzione con due argomenti, questi verrebbero archiviati in $_[0] e $_[1]. L'array @_ è a
array locale, ma i suoi elementi sono alias per i parametri scalari effettivi. In
particolare, se viene aggiornato un elemento $_[0], viene aggiornato l'argomento corrispondente (o
si verifica un errore se non è aggiornabile). Se un argomento è un array o un elemento hash che
non esisteva quando è stata chiamata la funzione, quell'elemento viene creato solo quando (e se) esso
viene modificato o si fa riferimento ad esso. (Alcune versioni precedenti di Perl creavano il
elemento indipendentemente dal fatto che l'elemento sia stato assegnato o meno.) Assegnazione all'intero array @_
rimuove tale aliasing e non aggiorna alcun argomento.

Un'istruzione "return" può essere utilizzata per uscire da una subroutine, specificando facoltativamente il valore restituito
valore, che verrà valutato nel contesto appropriato (elenco, scalare o vuoto)
a seconda del contesto della chiamata di subroutine. Se non specifichi alcun valore restituito, il
subroutine restituisce un elenco vuoto nel contesto dell'elenco, il valore indefinito nel contesto scalare,
o niente in un contesto vuoto. Se restituisci uno o più aggregati (array e hash),
questi saranno appiattiti insieme in un grande elenco indistinguibile.

Se non viene trovato alcun "return" e se l'ultima istruzione è un'espressione, viene restituito il suo valore.
Se l'ultima istruzione è una struttura di controllo del ciclo come un "foreach" o un "while", il
il valore restituito non è specificato. Il sottotitolo vuoto restituisce l'elenco vuoto.

A parte una struttura sperimentale (vedi "Firme" di seguito), Perl non ha un nome
parametri formali. In pratica, tutto ciò che fai è assegnare a un elenco "my()" di questi. Variabili
che non sono dichiarate private sono variabili globali. Per dettagli cruenti sulla creazione
variabili private, vedere "Variabili private tramite mio()" e "Valori temporanei tramite Locale()".
Per creare ambienti protetti per un insieme di funzioni in un pacchetto separato (e
probabilmente un file separato), vedere "Pacchetti" in perlmod.

Esempio:

sottomassimo {
mio $max = shift(@_);
foreach $pippo (@_) {
$max = $pippo se $max < $pippo;
}
restituire $max;
}
$giorno migliore = max($lun,$mar,$mer,$gio,$ven);

Esempio:

# ottieni una linea, combinando le linee di continuazione
# che iniziano con spazi bianchi

sub get_line {
$questa riga = $guarda avanti; # variabili globali!
LINEA: while (defined($lookahead = )) {
se ($lookahead =~ /^[ \t]/) {
$questa riga .= $guarda avanti;
}
else {
ultima linea;
}
}
restituisce $questa riga;
}

$previsione = ; # ottieni la prima riga
while (definito($linea = get_linea())) {
...
}

Assegnazione a un elenco di variabili private per nominare i tuoi argomenti:

sub forse set {
mia($chiave, $valore) = @_;
$Pippo{$chiave} = $valore a meno che $Pippo{$chiave};
}

Poiché l'assegnazione copia i valori, questo ha anche l'effetto di trasformare call-by-
riferimento in call-by-value. In caso contrario, una funzione è libera di apportare modifiche sul posto
di @_ e modificare i valori del chiamante.

upcase_in($v1, $v2); # questo cambia $v1 e $v2
sub maiuscolo_in {
per (@_) { tr/az/AZ/ }
}

Ovviamente non è consentito modificare le costanti in questo modo. Se un argomento fosse
in realtà letterale e hai provato a cambiarlo, avresti preso un'eccezione (presumibilmente fatale).
Ad esempio, questo non funzionerà:

upcase_in("federico");

Sarebbe molto più sicuro se la funzione "upcase_in()" fosse scritta per restituirne una copia
parametri invece di modificarli sul posto:

($v3, $v4) = maiuscolo($v1, $v2); # questo non cambia $v1 e $v2
sottomaiuscolo {
return a meno che non sia definito wantarray; # vuoto contesto, non fare nulla
i miei @parms = @_;
per (@parms) { tr/az/AZ/ }
ritorno wantarray ? @parms: $parms[0];
}

Nota come questa funzione (non prototipata) non si preoccupi se gli sono stati passati scalari reali o
matrici. Perl vede tutti gli argomenti come un unico grande, lungo e piatto elenco di parametri in @_. Questo è uno
area in cui risplende il semplice stile di Perl di passaggio di argomenti. La funzione "upcase()" sarebbe
funziona perfettamente senza modificare la definizione "upcase()" anche se gli abbiamo dato delle cose
come questo:

@newlist = maiuscolo(@list1, @list2);
@newlist = upcase(dividi /:/, $var);

Tuttavia, non essere tentato di fare questo:

(@a, @b) = maiuscolo(@lista1, @lista2);

Come l'elenco dei parametri in ingresso appiattito, anche l'elenco restituito viene appiattito al ritorno.
Quindi tutto ciò che sei riuscito a fare qui è archiviare tutto in @a e rendere @b vuoto. Vedere
"Passa per riferimento" per le alternative.

Una subroutine può essere chiamata usando un prefisso "&" esplicito. La "&" è facoltativa in moderno
Perl, così come le parentesi se la subroutine è stata predichiarata. Il "&" è non è un opzionale
quando si nomina semplicemente la subroutine, ad esempio quando è usata come argomento per definito() or
indefinito(). Né è facoltativo quando si desidera eseguire una chiamata di subroutine indiretta con a
nome o riferimento della subroutine utilizzando i costrutti "&$subref()" o "&{$subref}()", sebbene
la notazione "$subref->()" risolve questo problema. Vedi perlref per ulteriori informazioni su tutto ciò.

Le subroutine possono essere chiamate ricorsivamente. Se una subroutine viene chiamata utilizzando la forma "&", il
l'elenco degli argomenti è facoltativo e, se omesso, nessun array @_ è impostato per la subroutine: il
L'array @_ al momento della chiamata è invece visibile alla subroutine. Questa è un'efficienza
meccanismo che i nuovi utenti potrebbero voler evitare.

&foo(1,2,3); # passa tre argomenti
pippo(1,2,3); # lo stesso

pippo(); # passa una lista nulla
&pippo(); # lo stesso

& pippo; # foo() ottiene gli argomenti correnti, come foo(@_) !!
pippo; # like foo() IFF sub foo predichiarato, altrimenti "foo"

Il modulo "&" non solo rende l'elenco degli argomenti opzionale, ma disabilita anche qualsiasi prototipo
controllando gli argomenti forniti. Questo è in parte per ragioni storiche, e in parte
per avere un modo conveniente per imbrogliare se sai cosa stai facendo. Vedi "Prototipi"
qua sotto.

Dal Perl 5.16.0, il token "__SUB__" è disponibile in "use feature 'current_sub'" e
"usa 5.16.0". Valuterà un riferimento al sub attualmente in esecuzione, che consente
per le chiamate ricorsive senza conoscere il nome della subroutine.

usa 5.16.0;
mio $fattoriale = sub {
mio ($x) = @_;
restituisce 1 se $x == 1;
return($x * __SUB__->( $x - 1 ) );
};

Il comportamento di "__SUB__" all'interno di un blocco di codice regex (come "/(?{...})/") è soggetto a
cambiare.

Le subroutine i cui nomi sono tutti maiuscoli sono riservate al core Perl, così come lo sono
moduli i cui nomi sono tutti minuscoli. Una subroutine in tutte le maiuscole è un sottoprogramma
convenzione che significa che sarà chiamato indirettamente dal sistema di runtime stesso, di solito a causa
ad un evento innescato. Anche le subroutine il cui nome inizia con una parentesi sinistra sono
prenotato allo stesso modo. Quello che segue è un elenco di alcune subroutine che attualmente lo fanno
cose speciali, predefinite.

documentato più avanti in questo documento
"CARICAMENTO AUTOMATICO"

documentato in perlmod
"CLONE", "CLONE_SKIP",

documentato in perlobj
"DISTRUGGERE"

documentato in perltie
"BINMODE", "CLEAR", "CLOSE", "DELETE", "DESTROY", "EOF", "EXISTS", "EXTEND", "FETCH",
"FETCHSIZE", "FILENO", "FIRSTKEY", "GETC", "NEXTKEY", "OPEN", "POP", "PRINT",
"PRINTF", "PUSH", "READ", "READLINE", "SCALAR", "SEEK", "SHIFT", "SPLICE", "STORE",
"STORESIZE", "TELL", "TIEARRAY", "TIEHANDLE", "TIEHASH", "TIESCALAR", "UNSHIFT",
"SCOPRI", "SCRIVI"

documentato in PerlIO::via
"BINMODE", "CLEARERR", "CLOSE", "EOF", "ERROR", "FDOPEN", "FILENO", "FILL", "FLUSH",
"OPEN", "POPPED", "PUSHED", "READ", "SEEK", "SETLINEBUF", "SYSOPEN", "TELL", "UNREAD",
"UTF8", "SCRIVI"

documentato in perlfunc
"import", "unimport", "INC"

documentato in UNIVERSAL
"VERSIONE"

documentato in perldebguts
"DB::DB", "DB::sub", "DB::lsub", "DB::goto", "DB::rinviato"

non documentato, utilizzato internamente dalla funzione di sovraccarico
qualsiasi che inizia con "("

Le subroutine "BEGIN", "UNITCHECK", "CHECK", "INIT" e "END" non sono tanto
subroutine come blocchi di codice speciali denominati, di cui se ne può avere più di uno in a
pacchetto, e che puoi non è un chiamare esplicitamente. Vedere "BEGIN, UNITCHECK, CHECK, INIT e
FINE" in perlmod

firme
AVVERTIMENTO: le firme delle subroutine sono sperimentali. La funzione può essere modificata o rimossa
nelle future versioni di Perl.

Perl ha una struttura sperimentale per consentire ai parametri formali di una subroutine di essere
introdotto da una sintassi speciale, separata dal codice procedurale del corpo del sottoprogramma.
L'elenco dei parametri formali è noto come a firma. La struttura deve essere prima abilitata da
una dichiarazione pragmatica, "usa la funzione 'firme'", e produrrà un avvertimento a meno che
la categoria di avvertenze "sperimentale::firme" è disabilitata.

La firma fa parte del corpo di una subroutine. Normalmente il corpo di una subroutine è semplicemente
un blocco di codice rinforzato. Quando si utilizza una firma, la firma è un elenco tra parentesi
che va subito dopo il nome del sottoprogramma (o, per i sottoprogrammi anonimi,
subito dopo la parola chiave "sub"). La firma dichiara le variabili lessicali che sono
nell'ambito del blocco. Quando viene chiamata la subroutine, la firma assume per prima il controllo.
Popola le variabili della firma dall'elenco di argomenti che sono stati passati. Se la
l'elenco degli argomenti non soddisfa i requisiti della firma, quindi genererà un
eccezione. Al termine dell'elaborazione della firma, il controllo passa al blocco.

I parametri posizionali vengono gestiti semplicemente nominando le variabili scalari nella firma. Per
esempio,

sub foo ($sinistra, $destra) {
return $sinistra + $destra;
}

accetta due parametri posizionali, che devono essere riempiti in fase di esecuzione con due argomenti. Di
per impostazione predefinita i parametri sono obbligatori e non è consentito passare più argomenti di
previsto. Quindi quanto sopra è equivalente a

sottofondo {
die "Troppi argomenti per la subroutine" a meno che @_ <= 2;
die "Troppi pochi argomenti per la subroutine" a meno che @_ >= 2;
my $sinistra = $_[0];
mio $giusto = $_[1];
return $sinistra + $destra;
}

Un argomento può essere ignorato omettendo la parte principale del nome da un parametro
dichiarazione, lasciando solo un semplice sigillo "$". Per esempio,

sub foo ($primo, $, $terzo) {
return "primo=$primo, terzo=$terzo";
}

Sebbene l'argomento ignorato non vada in una variabile, è comunque obbligatorio per il
chiamante per passarlo.

Un parametro posizionale è reso facoltativo fornendo un valore predefinito, separato da
nome del parametro per "=":

sub pippo ($sinistra, $destra = 0) {
return $sinistra + $destra;
}

La suddetta subroutine può essere chiamata con uno o due argomenti. Il valore predefinito
l'espressione viene valutata quando viene chiamata la subroutine, quindi potrebbe fornire un valore predefinito diverso
valori per chiamate diverse. Viene valutato solo se l'argomento è stato effettivamente omesso
dalla chiamata. Per esempio,

mio $auto_id = 0;
sub foo ($cosa, $id = $auto_id++) {
print "$cosa ha ID $id";
}

assegna automaticamente ID sequenziali distinti alle cose per le quali non è stato fornito alcun ID da
il chiamante. Un'espressione di valore predefinito può anche fare riferimento a parametri precedenti nel
firma, facendo variare l'impostazione predefinita per un parametro in base ai parametri precedenti.
Per esempio,

sub foo ($nome, $cognome, $nickname = $nome) {
print "$nome $cognome è conosciuto come \"$nickname\"";
}

Un parametro facoltativo può essere senza nome proprio come un parametro obbligatorio. Per esempio,

sub foo ($cosa, $ = 1) {
stampa $cosa;
}

Il valore predefinito del parametro verrà comunque valutato se l'argomento corrispondente non lo è
fornito, anche se il valore non verrà memorizzato da nessuna parte. Questo è nel caso valutandolo
ha importanti effetti collaterali. Tuttavia, sarà valutato in un contesto nullo, quindi se è
non ha effetti collaterali e non è banale genererà un avviso se il "vuoto"
la categoria di avviso è abilitata. Se il valore predefinito di un parametro opzionale senza nome non è
importante, può essere omesso proprio come era il nome del parametro:

sub foo ($cosa, $=) {
stampa $cosa;
}

I parametri posizionali facoltativi devono venire dopo tutti i parametri posizionali obbligatori. (Se
non ci sono parametri posizionali obbligatori, quindi possono essere parametri posizionali facoltativi
la prima cosa nella firma.) Se ci sono più parametri posizionali opzionali
e non vengono forniti argomenti sufficienti per riempirli tutti, verranno riempiti da sinistra a
destra.

Dopo i parametri posizionali, è possibile acquisire argomenti aggiuntivi in ​​un parametro slurpy.
La forma più semplice di questo è solo una variabile array:

sub foo ($filtro, @input) {
print $filtro->($_) per ogni @input;
}

Con un parametro slurpy nella firma, non c'è limite massimo su quanti argomenti
può essere passato. Un parametro array slurpy può essere senza nome proprio come un parametro posizionale,
nel qual caso il suo unico effetto è disattivare il limite di argomenti che altrimenti
applicare:

sub foo ($cosa, @) {
stampa $cosa;
}

Un parametro slurpy può invece essere un hash, nel qual caso gli argomenti a sua disposizione sono
interpretati come chiavi e valori alternati. Ci devono essere tante chiavi quanti sono i valori: if
c'è un argomento strano, quindi verrà generata un'eccezione. Le chiavi saranno stringate e
se ci sono duplicati, l'istanza successiva ha la precedenza sulla precedente, come con
costruzione hash standard.

sub foo ($filtro, %input) {
print $filtro->($_, $input{$_}) per ogni chiave di ordinamento %input;
}

Un parametro hash slurpy può essere senza nome proprio come altri tipi di parametro. Ancora
insiste sul fatto che il numero di argomenti a sua disposizione sia pari, anche se non lo sono
essere inserito in una variabile.

sub foo ($cosa, %) {
stampa $cosa;
}

Un parametro slurpy, array o hash, deve essere l'ultima cosa nella firma. Esso può
seguire parametri posizionali obbligatori e facoltativi; potrebbe anche essere l'unica cosa nel
firma. I parametri Slurpy non possono avere valori predefiniti: se non vengono forniti argomenti per
li quindi ottieni un array vuoto o un hash vuoto.

Una firma può essere completamente vuota, nel qual caso non fa altro che controllare che il chiamante
non ha passato argomenti:

sub foo() {
123 ritorno;
}

Quando si utilizza una firma, gli argomenti sono ancora disponibili nella variabile array speciale
@_, oltre alle variabili lessicali della firma. C'è una differenza tra
le due modalità di accesso agli argomenti: @_ alias gli argomenti, ma la firma
le variabili ottengono copie degli argomenti. Quindi scrivere su una variabile di firma cambia solo
quella variabile e non ha effetto sulle variabili del chiamante, ma scrive su un elemento di
@_ modifica qualunque cosa il chiamante abbia usato per fornire quell'argomento.

Esiste una potenziale ambiguità sintattica tra firme e prototipi (vedi
"Prototipi"), perché entrambi iniziano con una parentesi aperta ed entrambi possono apparire in alcuni
degli stessi luoghi, ad esempio subito dopo il nome in una dichiarazione di subroutine. Per
ragioni storiche, quando le firme non sono abilitate, qualsiasi parentesi aperta in tale
contesto attiverà l'analisi del prototipo molto indulgente. La maggior parte delle firme sarà
interpretati come prototipi in quelle circostanze, ma non saranno prototipi validi. (Un valido
prototipo non può contenere alcun carattere alfabetico.) Ciò creerà un po' di confusione
messaggio di errore.

Per evitare ambiguità, quando le firme sono abilitate la sintassi speciale per i prototipi è
Disabilitato. Non c'è alcun tentativo di indovinare se un gruppo tra parentesi doveva essere un
prototipo o una firma. Per dare a una subroutine un prototipo in queste circostanze, usare
un attributo prototipo. Per esempio,

sub foo :prototipo($) { $_[0] }

È del tutto possibile che una subroutine abbia sia un prototipo che una firma. Essi
svolgere diversi lavori: il prototipo influisce sulla compilazione delle chiamate alla subroutine, e il
signature inserisce i valori degli argomenti nelle variabili lessicali in fase di runtime. Puoi quindi scrivere

sub foo ($sinistra, $destra): prototipo($$) {
return $sinistra + $destra;
}

L'attributo prototipo e qualsiasi altro attributo vengono dopo la firma.

Privata Variabili via mio()
Sinossi:

il mio $pippo; # dichiara $pippo lessicalmente locale
mio (@wid, %get); # dichiara l'elenco delle variabili local
mio $pippo = "flurp"; # dichiara $pippo lessicale e inizialo
mio @oof = @bar; # dichiara @oof lessicale e inizialo
mio $x : Pippo = $y; # simile, con un attributo applicato

AVVERTIMENTONota: l'uso di elenchi di attributi sulle "mie" dichiarazioni è ancora in evoluzione. Il corrente
la semantica e l'interfaccia sono soggette a modifiche. Vedere attributi e Attributo::Gestori.

L'operatore "my" dichiara che le variabili elencate sono lessicalmente confinate all'enclosure
blocco, condizionale ("if/unless/elsif/else"), loop ("for/foreach/while/until/continue"),
subroutine, file "eval" o "do/require/use". Se è elencato più di un valore, il
l'elenco deve essere inserito tra parentesi. Tutti gli elementi elencati devono essere lvalue legali. Soltanto
gli identificatori alfanumerici possono essere lessicalmente scoperti: i magici built-in come $/ devono attualmente
essere invece "localizzato" con "locale".

A differenza delle variabili dinamiche create dall'operatore "locale", le variabili lessicali dichiarate con
"my" sono totalmente nascosti al mondo esterno, comprese eventuali subroutine chiamate. Questo è
true se è la stessa subroutine chiamata da se stessa o da un'altra parte: ogni chiamata ha la sua
copia.

Ciò non significa che una variabile "my" dichiarata in un ambito lessicale che racchiude staticamente
sarebbe invisibile. Vengono tagliati solo gli ambiti dinamici. Ad esempio, il "bumpx()"
la funzione sottostante ha accesso alla variabile lessicale $x perché sia ​​​​"my" che "sub"
si è verificato nello stesso ambito, presumibilmente nell'ambito del file.

mio $x = 10;
subbumpx { $x++ }

Un "eval()", tuttavia, può vedere le variabili lessicali dell'ambito in cui viene valutato, quindi
purché i nomi non siano nascosti dalle dichiarazioni all'interno di "eval()" stesso. Vedi perlref.

L'elenco dei parametri per mio() può essere assegnato a se lo si desidera, il che consente di inizializzare
le tue variabili (Se non viene fornito alcun inizializzatore per una particolare variabile, viene creato con
il valore non definito.) Comunemente viene utilizzato per denominare i parametri di input in una subroutine.
Esempi:

$arg = "freddo"; # variabile "globale"
$ n = radice cubica(27);
print "$arg pensa che la radice sia $n\n";
fred pensa che la radice sia 3

sub radice_cubo {
my $arg = shift; # il nome non ha importanza
$argo **= 1/3;
return $ arg;
}

Il "mio" è semplicemente un modificatore su qualcosa a cui potresti assegnare. Quindi quando assegni a
variabili nella sua lista di argomenti, "my" non cambia se tali variabili sono viste come
uno scalare o un array. Così

mio ($pippo) = ; # SBAGLIATO?
il mio @FOO = ;

entrambi forniscono un contesto di elenco sul lato destro, mentre

mio $pippo = ;

fornisce un contesto scalare. Ma quanto segue dichiara solo una variabile:

mio $pippo, $bar = 1; # SBAGLIATO

Ha lo stesso effetto di

il mio $pippo;
$barra = 1;

La variabile dichiarata non viene introdotta (non è visibile) fino a dopo la corrente
dichiarazione. Così,

mio $x = $x;

può essere usato per inizializzare un nuovo $x con il valore del vecchio $x e l'espressione

mio $x = 123 e $x == 123

è false a meno che il vecchio $x non avesse il valore 123.

Gli ambiti lessicali delle strutture di controllo non sono delimitati precisamente dalle parentesi graffe che delimitano
i loro blocchi controllati; anche le espressioni di controllo fanno parte di tale ambito. Così nel
loop

mentre (la mia $line = <>) {
$riga = lc $riga;
} Continua {
stampa $riga;
}

l'ambito di $line si estende dalla sua dichiarazione al resto del costrutto del ciclo
(compresa la clausola "continua"), ma non oltre. Allo stesso modo, al condizionale

if ((la mia $risposta = ) =~ /^sì$/i) {
utente_concorda();
} elsif ($risposta =~ /^no$/i) {
utente_disaccordo();
} Else {
mastica $risposta;
die "'$risposta' non è né 'sì' né 'no'";
}

lo scopo di $ risposta si estende dalla sua dichiarazione attraverso il resto di quel condizionale,
comprese eventuali clausole "elsif" e "else", ma non oltre. Vedere "Dichiarazioni semplici" in
perlsyn per informazioni sull'ambito delle variabili nelle istruzioni con modificatori.

Il ciclo "foreach" per impostazione predefinita seleziona l'ambito della sua variabile indice in modo dinamico nel modo di
"Locale". Tuttavia, se la variabile indice è preceduta dalla parola chiave "my", o se esiste
già un lessico con quel nome nell'ambito, viene invece creato un nuovo lessico. così in
il cappio

per il mio $i (1, 2, 3) {
qualche_funzione();
}

l'ambito di $i si estende fino alla fine del ciclo, ma non oltre, rendendo il valore di
$i inaccessibile all'interno di "some_function()".

Alcuni utenti potrebbero voler incoraggiare l'uso di variabili con ambito lessicale. Come aiuto a
catturare usi impliciti per le variabili del pacchetto, che sono sempre globali, se dici

usa 'vars' rigorosi;

quindi qualsiasi variabile menzionata da lì alla fine del blocco che lo racchiude deve fare riferimento
a una variabile lessicale, essere predichiarata tramite "our" o "use vars", oppure deve essere completamente
qualificato con il nome del pacchetto. Altrimenti si verifica un errore di compilazione. Un blocco interno
può annullare questo con "nessun 'vars' rigoroso".

Un "my" ha sia un effetto di compilazione che di runtime. In fase di compilazione, il compilatore prende
avviso di esso. L'utilità principale di questo è quella di "usare 'vars' rigorosi", ma è
essenziale anche per la generazione di chiusure come dettagliato in perlref. Inizializzazione effettiva
viene ritardato fino al momento dell'esecuzione, tuttavia, quindi viene eseguito al momento opportuno, come ad esempio
ogni volta attraverso un ciclo, per esempio.

Le variabili dichiarate con "my" non fanno parte di alcun pacchetto e quindi non sono mai completamente
qualificato con il nome del pacchetto. In particolare, non ti è permesso provare a fare un
pacchetto variabile (o altro globale) lessicale:

mio $pack::var; # ERRORE! sintassi illegale

In effetti, una variabile dinamica (nota anche come pacchetto o variabili globali) è ancora
accessibile utilizzando la notazione pienamente qualificata "::" anche mentre un lessicale con lo stesso nome
è visibile anche:

pacchetto principale;
locale $x = 10;
mio $x = 20;
stampa "$x e $::x\n";

Verranno stampati 20 e 10.

Puoi dichiarare le "mie" variabili nell'ambito più esterno di un file per nasconderle
identificatori dal mondo esterno a quel file. Questo è simile nello spirito allo statico di C
variabili quando vengono utilizzate a livello di file. Per farlo con una subroutine è necessario il
uso di una chiusura (una funzione anonima che accede ai lessici di inclusione). Se lo desidera
creare una subroutine privata che non può essere chiamata dall'esterno di quel blocco, può dichiarare
una variabile lessicale contenente un sottoriferimento anonimo:

my $secret_version = '1.001-beta';
mio $sub_segreto = sub { print $versione_segreta};
&$secret_sub();

Finché il riferimento non viene mai restituito da alcuna funzione all'interno del modulo, non all'esterno
module può vedere la subroutine, perché il suo nome non è nella tabella dei simboli di nessun pacchetto.
Ricorda che non lo è DAVVERO chiamato $some_pack::secret_version o altro; è appena
$secret_version, non qualificato e non qualificabile.

Tuttavia, questo non funziona con i metodi oggetto; tutti i metodi oggetto devono essere nel
tabella dei simboli di qualche pacchetto da trovare. Vedere "Modelli di funzione" in perlref per
qualcosa di un work-around a questo.

Persistente Privata Variabili
Ci sono due modi per costruire variabili private persistenti in Perl 5.10. Per prima cosa, puoi
usa semplicemente la funzione "stato". Oppure puoi usare le chiusure, se vuoi rimanere compatibile
con versioni precedenti alla 5.10.

Persistente variabili via stato()

A partire da Perl 5.10.0, puoi dichiarare le variabili con la parola chiave "state" al posto di
"mio". Affinché funzioni, tuttavia, devi aver abilitato quella funzione in anticipo, tramite
usando il pragma "feature", o usando "-E" su one-liner (vedi caratteristica). Iniziando con
Perl 5.16, la forma "CORE::state" non richiede il pragma "feature".

La parola chiave "state" crea una variabile lessicale (seguendo le stesse regole di ambito di "my")
che persiste da una chiamata di subroutine alla successiva. Se una variabile di stato risiede all'interno di an
subroutine anonima, quindi ogni copia della subroutine ha la sua copia dello stato
variabile. Tuttavia, il valore della variabile di stato continuerà a persistere tra le chiamate a
la stessa copia del sottoprogramma anonimo. (Non dimenticare che "sub { ... }" crea un nuovo
subroutine ogni volta che viene eseguita.)

Ad esempio, il codice seguente mantiene un contatore privato, incrementato ogni volta che il
dammi_un altro() la funzione si chiama:

usa la funzione 'stato';
sub dammi_un altro { stato $x; ritorna ++$x }

E questo esempio utilizza subroutine anonime per creare contatori separati:

usa la funzione 'stato';
subcrea_contatore {
return sub { stato $x; ritorna ++$x }
}

Inoltre, poiché $x è lessicale, non può essere raggiunto o modificato da alcun codice Perl esterno.

Quando combinato con la dichiarazione di variabile, semplice assegnazione scalare a variabili "di stato" (come
in "stato $x = 42") viene eseguito solo la prima volta. Quando tali affermazioni vengono valutate
le volte successive, l'assegnazione viene ignorata. Il comportamento di questo tipo di incarico a
le variabili non scalari non sono definite.

Persistente variabili con chiusure

Solo perché una variabile lessicale è lessicalmente (chiamata anche staticamente) con scope al suo
racchiudendo block, "eval" o "do" FILE, questo non significa che all'interno di una funzione funzioni
come un C statico. Normalmente funziona più come un auto C, ma con spazzatura implicita
raccolta.

A differenza delle variabili locali in C o C++, le variabili lessicali di Perl non ottengono necessariamente
riciclati solo perché il loro ambito è uscito. Se qualcosa di più permanente è ancora consapevole
del lessico, rimarrà. Finché qualcos'altro fa riferimento a un lessico,
quel lessico non sarà liberato, il che è come dovrebbe essere. Non vorresti che la memoria fosse
gratuito fino a quando non hai finito di usarlo, o tenuto in giro una volta terminato. Immondizia automatica
la raccolta si occupa di questo per te.

Ciò significa che è possibile restituire o salvare riferimenti a variabili lessicali, mentre per
restituire un puntatore a un C auto è un grave errore. Ci dà anche un modo per simulare C's
statica delle funzioni. Ecco un meccanismo per assegnare a una funzione variabili private con entrambi
ambito lessicale e una durata statica. Se vuoi creare qualcosa come lo statico di C
variabili, racchiudere l'intera funzione in un blocco aggiuntivo e inserire la variabile statica
fuori dalla funzione ma nel blocco.

{
mio $valore_segreto = 0;
sub dammi_un altro {
return ++$ valore_segreto;
}
}
# $valore_segreto ora diventa irraggiungibile dall'esterno
# mondo, ma mantiene il suo valore tra le chiamate a dammi_un altro

Se questa funzione proviene da un file separato tramite "richiedi" o "usa", allora
questo probabilmente va bene. Se è tutto nel programma principale, dovrai organizzare
il "my" da eseguire in anticipo, mettendo l'intero blocco sopra il tuo programma principale,
o più probabilmente, posizionando semplicemente un blocco di codice "BEGIN" attorno ad esso per assicurarsi che ottenga
eseguito prima che il programma inizi a essere eseguito:

INIZIO {
mio $valore_segreto = 0;
sub dammi_un altro {
return ++$ valore_segreto;
}
}

Vedere "BEGIN, UNITCHECK, CHECK, INIT e END" in perlmod sullo speciale codice attivato
blocchi, "BEGIN", "UNITCHECK", "CHECK", "INIT" e "END".

Se dichiarato nell'ambito più esterno (l'ambito del file), i lessicali funzionano in qualche modo come i C
statica dei file. Sono disponibili per tutte le funzioni in quello stesso file dichiarato sotto di esse,
ma sono inaccessibili dall'esterno di quel file. Questa strategia viene talvolta utilizzata nei moduli
per creare variabili private che l'intero modulo può vedere.

Temporaneo Valori via Locale()
AVVERTIMENTO: In generale, dovresti usare "my" invece di "local", perché è più veloce e
più sicuro. Le eccezioni a questo includono le variabili di punteggiatura globali, filehandle globali
e formati, e la manipolazione diretta della stessa tabella dei simboli Perl. "locale" è principalmente
utilizzato quando il valore corrente di una variabile deve essere visibile alle subroutine richiamate.

Sinossi:

# localizzazione dei valori

locale $ pippo; # rendi $pippo dinamicamente locale
locale (@wid, %get); # crea un elenco di variabili locali
locale $pippo = "flurp"; # rendi $pippo dinamico e inizialo
local @oof = @bar; # rendi @oof dinamico e inizialo

locale $hash{chiave} = "val"; # imposta un valore locale per questa voce hash
elimina $hash{chiave} locale; # cancella questa voce per il blocco corrente
locale ($cond ? $v1 : $v2); # supporto per diversi tipi di lvalue
# localizzazione

# localizzazione dei simboli

locale *FH; # localizza $FH, @FH, %FH, &FH ...
locale *merlyn = *randal; # ora $merlyn è in realtà $randal, in più
# @merlyn è davvero @randal, ecc
locale *merlyn = 'randal'; # STESSA COSA: promuovere 'randal' a *randal
locale *merlyn = \$randal; # solo alias $merlyn, non @merlyn ecc

Un "locale" modifica le sue variabili elencate per essere "locali" rispetto al blocco che lo racchiude, "eval", o
"fare FILE"--e per in qualsiasi sottoprogramma detto da entro che bloccare. Un "locale" dà solo
valori temporanei a variabili globali (che significa pacchetto). lo fa non è un creare un locale
variabile. Questo è noto come ambito dinamico. L'ambito lessicale viene eseguito con "mio", che
funziona più come le dichiarazioni automatiche di C.

Anche alcuni tipi di lvalue possono essere localizzati: elementi hash e array e sezioni,
condizionali (a condizione che il loro risultato sia sempre localizzabile) e riferimenti simbolici.
Per quanto riguarda le variabili semplici, questo crea nuovi valori con ambito dinamico.

Se più di una variabile o espressione viene assegnata a "local", devono essere posizionate in
parentesi. Questo operatore funziona salvando i valori correnti di quelle variabili nella sua
elenco di argomenti su uno stack nascosto e ripristinarli all'uscita dal blocco, dalla subroutine o
eval. Ciò significa che le subroutine chiamate possono anche fare riferimento alla variabile locale, ma non
quello globale. L'elenco degli argomenti può essere assegnato se lo si desidera, il che consente di
inizializza le variabili locali. (Se non viene fornito alcun inizializzatore per una particolare variabile,
viene creato con un valore indefinito.)

Poiché "local" è un operatore di runtime, viene eseguito ogni volta attraverso un ciclo.
Di conseguenza, è più efficiente localizzare le variabili al di fuori del ciclo.

Grammaticale Nota on Locale()

Un "locale" è semplicemente un modificatore su un'espressione lvalue. Quando assegni a un "local"ized
variabile, il "locale" non cambia se il suo elenco è visto come uno scalare o un array.
So

local($pippo) = ;
locale @FOO = ;

entrambi forniscono un contesto di elenco sul lato destro, mentre

locale $pippo = ;

fornisce un contesto scalare.

Localizzazione of la nostra speciale variabili

Se localizzi una variabile speciale, le darai un nuovo valore, ma è magico
non andrà via. Ciò significa che tutti gli effetti collaterali relativi a questa magia funzionano ancora con il
valore localizzato.

Questa funzione consente a un codice come questo di funzionare:

# Leggi l'intero contenuto di FILE in $slurp
{ $/ locale = undef; $slurp = ; }

Si noti, tuttavia, che ciò limita la localizzazione di alcuni valori; per esempio, il
la seguente istruzione muore, a partire da perl 5.10.0, con un errore Modifica of a sola lettura
APPREZZIAMO tentato, perché la variabile $1 è magica e di sola lettura :

locale $1 = 2;

Un'eccezione è la variabile scalare predefinita: a partire da perl 5.14 "local($_)" will
rimuovere sempre tutta la magia da $_, per rendere possibile il riutilizzo sicuro di $_ in una subroutine.

AVVERTIMENTONota: la localizzazione di array e hash collegati non funziona attualmente come descritto.
Questo problema verrà risolto in una versione futura di Perl; nel frattempo, evita il codice che si basa su
qualsiasi comportamento particolare di localizzazione di array o hash legati (localizzazione di individui
elementi è ancora a posto). Vedere "La localizzazione di array e hash legati è interrotta" in perl58delta
per ulteriori dettagli.

Localizzazione of globi

il costrutto

*nome locale;

crea una nuova voce nella tabella dei simboli per il glob "name" nel pacchetto corrente. Quella
significa che tutte le variabili nel suo slot glob ($name, @name, %name, &name e il "name"
filehandle) vengono ripristinati dinamicamente.

Ciò implica, tra le altre cose, che qualsiasi magia eventualmente trasportata da quelle variabili è
localmente perso. In altre parole, dire "local */" non avrà alcun effetto sull'interno
valore del separatore di record di input.

Localizzazione of elementi of composito Tipi di

Vale anche la pena dedicare un momento a spiegare cosa succede quando si "localizza" un membro di a
tipo composito (cioè un array o un elemento hash). In questo caso, l'elemento è "localizzato"
by Nome. Ciò significa che quando l'ambito di "local()" termina, il valore salvato sarà
ripristinato nell'elemento hash la cui chiave è stata nominata in "local()", o nell'elemento dell'array
il cui indice è stato nominato in "local()". Se quell'elemento è stato eliminato mentre "local()"
era in vigore (ad esempio da un "delete()" da un hash o da uno "shift()" di un array), lo farà
torna in vita, eventualmente estendendo una matrice e riempiendo il saltato
elementi con "undef". Ad esempio, se dici

%hash = ( 'Questo' => 'è', 'a' => 'prova' );
@ary = ( 0..5 );
{
locale($ario[5]) = 6;
local($hash{'a'}) = 'trapano';
while (mio $e = pop(@ary)) {
print "$e . . .\n";
ultimo a meno che $e > 3;
}
se (@ary) {
$hash{'solo a'} = 'prova';
cancella $hash{'a'};
}
}
print join(' ', map { "$_ $hash{$_}" } chiavi di ordinamento %hash),".\n";
print "L'array ha ",scalar(@ary)," elementi: ",
join(', ', map { definito $_ ? $_ : 'undef' } @ary),"\n";

Perl stamperà

6. . .
4. . .
3. . .
Questo è un test solo un test.
L'array ha 6 elementi: 0, 1, 2, undef, undef, 5

Il comportamento di Locale() su membri inesistenti di tipi composti è soggetto a modifiche in
futuro.

Localizzata cancellazione of elementi of composito Tipi di

Puoi usare i costrutti "delete local $array[$idx]" e "delete local $hash{key}" per
eliminare una voce di tipo composto per il blocco corrente e ripristinarla quando termina. Essi
restituisce il valore dell'array/hash prima della localizzazione, il che significa che lo sono
rispettivamente equivalente a

fare {
mio $val = $array[$idx];
locale $array[$idx];
elimina $array[$idx];
$ valore
}

e

fare {
mio $val = $hash{chiave};
locale $hash{chiave};
elimina $hash{chiave};
$ valore
}

tranne che per quelli il "local" è limitato al blocco "do". Sono accettate anche le fette.

il mio %hash = (
a => [ 7, 8, 9 ],
b => 1,
)

{
my $a = cancella $hash{a} locale;
# $a è [ 7, 8, 9 ]
# % hash è (b => 1)

{
my @nums = elimina locale @$a[0, 2]
# @num è (7, 9)
# $a è [ undef, 8 ]

$a[0] = 999; # verrà cancellato al termine dell'ambito
}
# $a è tornato a [ 7, 8, 9 ]

}
# %hash è tornato al suo stato originale

Lvalore subroutine
È possibile restituire un valore modificabile da una subroutine. Per fare questo, devi
dichiarare la subroutine per restituire un lvalue.

mio $val;
subcanmod: lvalue {
$val; # oppure: restituisce $val;
}
subnomodo {
$ val;
}

canmod() = 5; # assegna a $val
nomod() = 5; # ERRORE

Il contesto scalare/lista per la subroutine e per il lato destro dell'assegnazione è
determinato come se la chiamata di subroutine fosse sostituita da uno scalare. Ad esempio, considera:

dati(2,3) = get_data(3,4);

Entrambe le subroutine qui sono chiamate in un contesto scalare, mentre in:

(dati(2,3)) = get_data(3,4);

e in:

(dati(2),dati(3)) = ottieni_dati(3,4);

tutte le subroutine vengono chiamate in un contesto di lista.

Le subroutine Lvalue sono convenienti, ma devi tenere presente che, se utilizzate con
oggetti, possono violare l'incapsulamento. Un normale mutatore può controllare l'argomento fornito
prima di impostare l'attributo che sta proteggendo, una subroutine lvalue non può. Se tu
richiedono un'elaborazione speciale durante l'archiviazione e il recupero dei valori, considerare l'utilizzo del
Modulo CPAN Sentinel o qualcosa di simile.

Lessicale subroutine
AVVERTIMENTO: I sottoprogrammi lessicali sono ancora sperimentali. La funzione può essere modificata o
rimosso nelle versioni future di Perl.

Le subroutine lessicali sono disponibili solo con il pragma "use feature 'lexical_subs'",
che produce un avviso a meno che la categoria di avvisi "sperimentale::lexical_subs" non sia
Disabilitato.

A partire da Perl 5.18, è possibile dichiarare una subroutine privata con "my" o "state". Come
con le variabili di stato, la parola chiave "stato" è disponibile solo in "usa la funzione 'stato'" o
"usa 5.010" o superiore.

Queste subroutine sono visibili solo all'interno del blocco in cui sono dichiarate e solo
dopo tale dichiarazione:

nessun avviso "sperimentale::lexical_subs";
usa la funzione 'lexical_subs';

pippo(); # chiama il pacchetto/subroutine globale
stato sub foo {
pippo(); # chiama anche la subroutine del pacchetto
}
pippo(); # chiama "stato" sub
mio $rif = \&pippo; # prendi un riferimento a "stato" sub

la mia barra secondaria { ... }
sbarra(); # chiama il "mio" sub

Per utilizzare una subroutine lessicale dall'interno della subroutine stessa, è necessario predichiararla.
La sintassi di definizione della subroutine "sub foo {...}" rispetta qualsiasi precedente "my sub;" o "stato
sub;" dichiarazione.

il mio sub baz; # predichiarazione
sub baz { # definisce il "mio" sub
baz(); # chiamata ricorsiva
}

"stato sub" vs "mio sub"

Qual è la differenza tra i sottotitoli "stato" e i "miei"? Ogni volta che l'esecuzione
entra in un blocco quando vengono dichiarati i "miei" sub, viene creata una nuova copia di ogni sub. "Stato"
le subroutine persistono da un'esecuzione del blocco contenitore alla successiva.

Quindi, in generale, le subroutine di "stato" sono più veloci. Ma i "miei" sottotitoli sono necessari se vuoi
per creare chiusure:

nessun avviso "sperimentale::lexical_subs";
usa la funzione 'lexical_subs';

sotto qualunque cosa {
mio $x = spostamento;
il mio sub interiore {
... fai qualcosa con $ x ...
}
interno();
}

In questo esempio, viene creato un nuovo $x quando viene chiamato "qualunque" e anche un nuovo "inner",
che può vedere il nuovo $x. Un sub "stato" vedrà solo la $x dalla prima chiamata a
"qualunque cosa".

"nostro" subroutine

Come "nostra $variabile", "nostro sub" crea un alias lessicale per la subroutine del pacchetto di
stesso nome.

I due usi principali per questo sono tornare a usare il pacchetto sub all'interno di un inner
scopo:

nessun avviso "sperimentale::lexical_subs";
usa la funzione 'lexical_subs';

subfoo { ... }

sottobarra {
il mio sottofoo { ... }
{
# è necessario utilizzare il foo esterno qui
il nostro sub-foo;
pippo();
}
}

e per rendere visibile una subroutine ad altri pacchetti nello stesso ambito:

pacchetto MySneakyModule;

nessun avviso "sperimentale::lexical_subs";
usa la funzione 'lexical_subs';

il nostro sub fa_qualcosa { ... }

sub fai_qualcosa_con_chiamante {
pacchetto DB;
() = chiamante 1; # set @DB::args
fai_qualcosa(@args); # usa MySneakyModule::fai_qualcosa
}

Di passaggio Simbolo Table Inserimenti (tipo globi)
AVVERTIMENTO: Il meccanismo descritto in questa sezione era originariamente l'unico modo per simulare
pass-by-reference nelle versioni precedenti di Perl. Anche se funziona ancora bene nel moderno
versioni, il nuovo meccanismo di riferimento è generalmente più facile da utilizzare. Vedi sotto.

A volte non vuoi passare il valore di un array a una subroutine ma piuttosto il nome
di esso, in modo che la subroutine possa modificarne la copia globale invece di lavorare con a
copia locale. In perl puoi fare riferimento a tutti gli oggetti con un nome particolare anteponendo il
nome con una stella: *pippo. Questo è spesso noto come "typeglob", perché la stella sul
front può essere pensato come una corrispondenza con caratteri jolly per tutti i caratteri prefissi divertenti su
variabili e sottoprogrammi e simili.

Quando valutato, typeglob produce un valore scalare che rappresenta tutti gli oggetti di
quel nome, incluso qualsiasi filehandle, formato o subroutine. Quando viene assegnato a, provoca
il nome citato per riferirsi a qualunque valore "*" gli fosse assegnato. Esempio:

subdoppio {
locale(*qualcosa) = @_;
foreach $elem (@someary) {
$elemento *= 2;
}
}
doubleary(*pippo);
doppio(*bar);

Gli scalari sono già passati per riferimento, quindi puoi modificare gli argomenti scalari senza usare
questo meccanismo facendo esplicito riferimento a $_[0] ecc. Puoi modificare tutti gli elementi di
un array passando tutti gli elementi come scalari, ma devi usare il meccanismo "*" (o
il meccanismo di riferimento equivalente) per "push", "pop" o modificare la dimensione di un array. Esso
sarà sicuramente più veloce passare il typeglob (o riferimento).

Anche se non vuoi modificare un array, questo meccanismo è utile per passarne più di uno
array in un singolo LIST, perché normalmente il meccanismo LIST unirà tutti gli array
valori in modo da non poter estrarre i singoli array. Per ulteriori informazioni sui typeglob, vedere
"Typeglob e Filehandle" in perldata.

Quando a Ancora Usa il Locale()
Nonostante l'esistenza del "mio", ci sono ancora tre luoghi in cui l'operatore "locale"
brilla ancora. Infatti, in questi tre posti, tu devono obbligatoriamente: usa "local" invece di "my".

1. È necessario assegnare a una variabile globale un valore temporaneo, in particolare $_.

Le variabili globali, come @ARGV o le variabili di punteggiatura, devono essere "localizzate"
con "locale()". Questo blocco legge in /etc/motd, e lo divide in pezzi separati
da linee di segno di uguale, che sono posizionate in @Fields.

{
local @ARGV = ("/etc/motd");
locale $/ = undef;
locale $_ = <>;
@Fields = dividi /^\s*=+\s*$/;
}

In particolare, è importante "localizzare" $_ in qualsiasi routine che gli assegni.
Cerca le assegnazioni implicite nei condizionali "while".

2. È necessario creare un file locale o un handle di directory o una funzione locale.

Una funzione che necessita di un proprio filehandle deve usare "local()" su un completo
typeglob. Questo può essere usato per creare nuove voci della tabella dei simboli:

sottocoda {
locale (*READER, *WRITER); # non è mio!
pipe (READER, WRITER) o die "pipe: $!";
ritorno (*LETTORE, *SCRITTORE);
}
($testa, $coda) = ioqueue();

Vedere il modulo Simboli per un modo per creare voci di tabelle di simboli anonime.

Poiché l'assegnazione di un riferimento a un typeglob crea un alias, questo può essere usato per
creare quella che è effettivamente una funzione locale, o almeno un alias locale.

{
locale *cresci = \&rimpicciolisci; # solo fino all'uscita di questo blocco
crescere(); # chiama davvero strizzacervelli()
spostare(); # se move() cresce(), si riduce anche()
}
crescere(); # ottieni di nuovo il vero grow()

Vedi "Modelli di funzione" in perlref per ulteriori informazioni sulla manipolazione delle funzioni per nome in
per di qua.

3. Si desidera modificare temporaneamente solo un elemento di un array o di un hash.

Puoi "localizzare" solo un elemento di un aggregato. Di solito questo viene fatto su
dinamica:

{
local $SIG{INT} = 'IGNORA';
funzione(); # non interrompibile
}
# interrompibilità ripristinata automaticamente qui

Ma funziona anche su aggregati lessicalmente dichiarati.

Passare by Referenze
Se vuoi passare più di un array o hash in una funzione, o restituirli da
it--e fai in modo che mantengano la loro integrità, quindi dovrai usare un'esplicita
passante per riferimento. Prima di farlo, è necessario comprendere i riferimenti come dettagliato in
perlrif. Questa sezione potrebbe non avere molto senso per te altrimenti.

Ecco alcuni semplici esempi. Per prima cosa, passiamo diversi array a una funzione e
fallo "saltare" tutto, quindi, restituendo un nuovo elenco di tutti i loro ultimi elementi precedenti:

@tailings = popmany ( \@a, \@b, \@c, \@d );

sottopopolare {
il mio $aref;
la mia @retlist = ();
per ogni $aref ( @_ ) {
premi @retlist, pop @$aref;
}
ritorna @retlist;
}

Ecco come potresti scrivere una funzione che restituisca un elenco di chiavi che si verificano in tutti i
hash passati ad esso:

@common = inter( \%pippo, \%bar, \%joe );
sub inter {
mio ($k, $href, %visto); # locali
per ogni $href (@_) {
while ( $k = ogni %$href ) {
$visto{$k}++;
}
}
return grep { $visto{$_} == @_ } chiavi %viste;
}

Finora, stiamo usando solo il normale meccanismo di restituzione dell'elenco. Cosa succede se vuoi
passare o restituire un hash? Bene, se ne stai usando solo uno o non ti dispiace
la concatenazione, quindi la normale convenzione di chiamata è ok, anche se un po' costosa.

Dove le persone si mettono nei guai è qui:

(@a, @b) = funzione(@c, @d);
or
(%a, %b) = funzione(%c, %d);

Quella sintassi semplicemente non funzionerà. Imposta solo @a o %a e cancella @b o %b. più il
la funzione non è stata passata in due array o hash separati: ha ottenuto un lungo elenco in @_,
come sempre.

Se riesci a fare in modo che tutti se ne occupino attraverso i riferimenti, è un codice più pulito,
anche se non così bello da vedere. Ecco una funzione che accetta due riferimenti di array come
argomenti, restituendo i due elementi dell'array in ordine di quanti elementi hanno in
loro:

($aref, $bref) = funzione(\@c, \@d);
print "@$aref ha più di @$bref\n";
sub funzione {
mio ($cref, $dref) = @_;
if (@$cref > @$dref) {
ritorno ($cref, $dref);
} Else {
ritorno ($dref, $cref);
}
}

Si scopre che puoi effettivamente fare anche questo:

(*a, *b) = funzione(\@c, \@d);
print "@a ha più di @b\n";
sub funzione {
locale (*c, *d) = @_;
se (@c > @d) {
ritorno (\@c, \@d);
} Else {
ritorno (\@d, \@c);
}
}

Qui stiamo usando i typeglobs per fare l'aliasing della tabella dei simboli. È un po' sottile, però,
e inoltre non funzionerà se stai usando le "mie" variabili, perché solo i globali (anche sotto mentite spoglie
come "local") sono nella tabella dei simboli.

Se stai passando i filehandle, di solito puoi semplicemente usare il semplice typeglob, come
*STDOUT, ma funzionano anche i riferimenti a typeglobs. Per esempio:

sputacchiare(\*STDOUT);
sottovoce {
mio $fh = shift;
print $fh "lei um bene a hmmm\n";
}

$rec = get_rec(\*STDIN);
sub get_rec {
mio $fh = shift;
restituisce scalare <$fh>;
}

Se hai intenzione di generare nuovi filehandle, puoi farlo. Avviso per ripassare
solo il nudo *FH, non il suo riferimento.

sub apri {
mio $percorso = shift;
locale *FH;
ritorno aperto (FH, $percorso) ? *FH : indefinito;
}

prototipi
Perl supporta un tipo molto limitato di controllo degli argomenti in fase di compilazione utilizzando la funzione
prototipazione. Questo può essere dichiarato nella sezione PROTO o con un prototipo
attributo. Se dichiari uno dei due

sotto il mio push (+@)
sub mypush :prototipo(+@)

quindi "mypush()" accetta gli argomenti esattamente come fa "push()".

Se le firme di subroutine sono abilitate (vedi "Firme"), la sintassi PROTO più breve è
indisponibile, perché si scontrerebbe con le firme. In tal caso, un prototipo può solo
essere dichiarato sotto forma di attributo.

La dichiarazione della funzione deve essere visibile in fase di compilazione. Il prototipo colpisce solo
interpretazione delle chiamate new-style alla funzione, dove new-style è definito come non in uso
il personaggio. In altre parole, se la chiami come una funzione incorporata, allora
si comporta come una funzione incorporata. Se la chiami come una subroutine vecchio stile, allora
si comporta come una subroutine vecchio stile. Nasce naturalmente da questa regola che
i prototipi non hanno alcuna influenza sui riferimenti di subroutine come "\&pippo" o su indiretti
chiamate di subroutine come "&{$subref}" o "$subref->()".

Anche le chiamate ai metodi non sono influenzate dai prototipi, perché la funzione da chiamare è
indeterminato in fase di compilazione, poiché il codice esatto chiamato dipende dall'ereditarietà.

Perché l'intento di questa funzione è principalmente quello di permetterti di definire subroutine che funzionano
come le funzioni integrate, ecco i prototipi per alcune altre funzioni che analizzano quasi
esattamente come il corrispondente integrato.

Dichiarato come chiamato come

sub miolink ($$) miolink $vecchio, $nuovo
sub miovec ($$$) miovec $var, $offset, 1
sub mioindice ($$;$) mioindice &getstring, "substr"
sub mysyswrite ($$$;$) mysyswrite $buf, 0, lunghezza($buf) - $off, $off
sub mioreverse (@) mioreverse $a, $b, $c
sub miojoin ($@) miojoin ":", $a, $b, $c
sub miopop (+) miopop @array
sub mysplice (+$$@) mysplice @array, 0, 2, @pushme
sub miechiavi (+) miechiavi %{$hashref}
sub myopen (*;$) myopen HANDLE, $nome
sub mypipe (**) mypipe READHANDLE, WRITHANDLE
sub miogrep (&@) miogrep { /pippo/ } $a, $b, $c
sotto mirrando (;$) mirrando 42
sub mytime() mytime

Qualsiasi carattere prototipo con barra rovesciata rappresenta un argomento effettivo che deve iniziare con
quel carattere (facoltativamente preceduto da "mio", "nostro" o "locale"), ad eccezione di "$",
che accetterà qualsiasi espressione lvalue scalare, come "$foo = 7" o
"mia_funzione()->[0]". Il valore passato come parte di @_ sarà un riferimento all'effettivo
argomento dato nella chiamata della subroutine, ottenuto applicando "\" a quell'argomento.

Puoi usare la notazione del gruppo barra rovesciata "\[]" per specificare più di un argomento consentito
genere. Per esempio:

sub myref (\[$@%&*])

consentirà di chiamare miorif() as

miref $var
myref @array
myref%hash
mioref &sub
miref *glob

e il primo argomento di miorif() sarà un riferimento a uno scalare, un array, un hash, a
codice o un glob.

I caratteri prototipo senza barra hanno significati speciali. Qualsiasi "@" o "%" senza barra rovesciata
mangia tutti gli argomenti rimanenti e forza il contesto dell'elenco. Un argomento rappresentato da "$"
forza il contesto scalare. Un "&" richiede una subroutine anonima, che, se passata come
primo argomento, non richiede la parola chiave "sub" o una virgola successiva.

Un "*" consente alla subroutine di accettare una bareword, una costante, un'espressione scalare, typeglob,
o un riferimento a un typeglob in quello slot. Il valore sarà disponibile per la subroutine
sia come semplice scalare, sia (negli ultimi due casi) come riferimento al typeglob.
Se desideri convertire sempre tali argomenti in un riferimento typeglob, usa
Simbolo::qualify_to_ref() come segue:

usa il simbolo 'qualify_to_ref';

sottofoo (*) {
my $fh = qualifiche_a_ref(shift, chiamante);
...
}

Il prototipo "+" è un'alternativa speciale a "$" che agirà come "\[@%]" quando viene assegnato un
array letterale o variabile hash, ma altrimenti forzerà il contesto scalare sull'argomento.
Questo è utile per le funzioni che dovrebbero accettare un array letterale o un array
riferimento come argomento:

sub miopush (+@) {
il mio $aref = turno;
die "Non è un array o arrayref" a meno che ref $aref eq 'ARRAY';
premi @$aref, @_;
}

Quando si utilizza il prototipo "+", la funzione deve verificare che l'argomento sia di an
tipo accettabile.

Un punto e virgola (";") separa gli argomenti obbligatori dagli argomenti facoltativi. È ridondante
prima di "@" o "%", che divorano tutto il resto.

Come ultimo carattere di un prototipo, o appena prima di un punto e virgola, un "@" o un "%", puoi
usa "_" al posto di "$": se questo argomento non viene fornito, verrà utilizzato $_.

Nota come gli ultimi tre esempi nella tabella sopra sono trattati in modo speciale dal parser.
"mygrep()" viene analizzato come un vero operatore di lista, "myrand()" viene analizzato come un vero unario
operatore con precedenza unaria uguale a "rand()" e "mytime()" è veramente senza
argomenti, proprio come "time()". Cioè, se dici

il mio tempo +2;

otterrai "mytime() + 2", non mio tempo(2), che è come sarebbe analizzato senza a
prototipo. Se vuoi forzare una funzione unaria ad avere la stessa precedenza di una lista
operatore, aggiungi ";" alla fine del prototipo:

sub miogetprotobynumero($;);
mygetprotobynumber $a > $b; # analizzato come mygetprotobynumber($a > $b)

La cosa interessante di "&" è che puoi generare una nuova sintassi con esso, a condizione che sia
nella posizione iniziale:

sottoprova (&@) {
mio($prova,$cattura) = @_;
eval { &$prova };
se ($@) {
locale $_ = $@;
&$cattura;
}
}
cattura secondaria (&) { $_[0] }

provare {
muori "fooey";
} catturare {
/phooey/ e stampa "unphooey\n";
};

Che stampa "unphooey". (Sì, ci sono ancora problemi irrisolti che hanno a che fare con
visibilità di @_. Sto ignorando questa domanda per il momento. (Ma nota che se facciamo
@_ con ambito lessicale, quelle subroutine anonime possono agire come chiusure... (Accidenti, è questo?
suona un po' lispish? (Non importa.))))

Ed ecco una reimplementazione dell'operatore Perl "grep":

sub mygrep (&@) {
mio $codice = shift;
il mio @risultato;
per ogni $_ (@_) {
push(@result, $_) if &$code;
}
@risultato;
}

Alcune persone preferirebbero prototipi alfanumerici completi. Gli alfanumerici sono stati
lasciato intenzionalmente fuori dai prototipi per lo scopo preciso di un giorno in futuro
aggiungendo parametri formali con nome. L'obiettivo principale dell'attuale meccanismo è lasciare che module
i writer forniscono una migliore diagnostica per gli utenti del modulo. Larry sente abbastanza la notazione
comprensibile ai programmatori Perl, e che non si intrometterà molto nella carne di
il modulo, né renderlo più difficile da leggere. Il rumore di linea è visivamente incapsulato in a
piccola pillola facile da ingoiare.

Se provi a utilizzare una sequenza alfanumerica in un prototipo genererai un optional
warning - "Carattere illegale nel prototipo...". Sfortunatamente versioni precedenti di Perl
consentiva l'utilizzo del prototipo purché il suo prefisso fosse un prototipo valido. L'avviso
potrebbe essere aggiornato a un errore fatale in una versione futura di Perl una volta che la maggior parte di
il codice incriminato è corretto.

Probabilmente è meglio prototipare nuove funzioni, non adattare la prototipazione a quelle più vecchie.
Questo perché devi stare particolarmente attento alle imposizioni silenziose di elenchi diversi
rispetto a contesti scalari. Ad esempio, se decidi che una funzione dovrebbe occuparne solo uno
parametro, in questo modo:

sottofunzione ($) {
mio $n = spostamento;
print "mi hai dato $n\n";
}

e qualcuno lo ha chiamato con un array o un'espressione che restituisce un elenco:

funzione(@pippo);
funzione(dividi /:/ );

Quindi hai appena fornito uno "scalare" automatico davanti al loro argomento, che può essere
più che sorprendente. Il vecchio @pippo che conteneva una cosa non viene superato
in. Invece, "func()" ora viene passato in un 1; ovvero il numero di elementi in @foo.
E lo "split" viene chiamato in un contesto scalare, quindi inizia a scarabocchiare sul tuo parametro @_
elenco. Ahia!

Se un sottotitolo ha sia un PROTO che un BLOCCO, il prototipo non viene applicato fino a dopo il BLOCCO
è completamente definito. Ciò significa che una funzione ricorsiva con un prototipo deve essere
pre-dichiarato affinché il prototipo abbia effetto, in questo modo:

sottofoo($$);
sottofoo($$) {
pippo 1, 2;
}

Tutto questo è molto potente, ovviamente, e dovrebbe essere usato solo con moderazione per rendere il
mondo un posto migliore.

costante funzioni
Le funzioni con un prototipo di "()" sono potenziali candidati per l'inlining. Se il risultato
dopo l'ottimizzazione e il ripiegamento costante è uno scalare costante o con ambito lessicale
che non ha altri riferimenti, verrà utilizzato al posto delle chiamate di funzione effettuate
privo di "&". Le chiamate effettuate utilizzando "&" non sono mai in linea. (Vedere costante.pm per un modo semplice per
dichiarare la maggior parte delle costanti.)

Le seguenti funzioni sarebbero tutte inline:

sub pi() { 3.14159 } # Non esatto, ma vicino.
sub PI () { 4 * atan2 1, 1 } # Per quanto buono,
# ed è anche in linea!
sotto ST_DEV () { 0 }
sub ST_INO () { 1 }

sub FLAG_FOO () { 1 << 8 }
sub FLAG_BAR () { 1 << 9 }
sub FLAG_MASK () { FLAG_FOO | FLAG_BAR }

sub OPT_BAZ () { non (0x1B58 & FLAG_MASK) }

sub N () { int(OPT_BAZ) / 3 }

sub FOO_SET () { 1 se FLAG_MASK & FLAG_FOO }
sub FOO_SET2 () { if (FLAG_MASK & FLAG_FOO) { 1 } }

(Si noti che l'ultimo esempio non era sempre in linea in Perl 5.20 e versioni precedenti, il che lo faceva
non comportarsi in modo coerente con le subroutine contenenti ambiti interni.) È possibile annullare l'ordine
inline utilizzando un "ritorno" esplicito:

sub baz_val() {
se (OPT_BAZ) {
23 ritorno;
}
else {
42 ritorno;
}
}
sub bonk_val () { ritorno 12345 }

Come accennato in precedenza, puoi anche dichiarare i sottotitoli inline in modo dinamico all'inizio del tempo se il loro
body è costituito da uno scalare lessicale che non ha altri riferimenti. Solo il primo
esempio qui sarà inlineato:

INIZIO {
mia $var = 1;
nessun "riferimento" rigoroso;
*INLINED = sub() { $var };
}

INIZIO {
mia $var = 1;
mio $rif = \$var;
nessun "riferimento" rigoroso;
*NON_INLINED = sub() { $var };
}

Un avvertimento non così ovvio con questo (vedi [RT #79908]) è che la variabile sarà
immediatamente inline, e smetterà di comportarsi come una normale variabile lessicale, ad esempio questo sarà
stampa 79907, non 79908:

INIZIO {
mio $x = 79907;
*RT_79908 = sub() { $x };
$x++;
}
stampa RT_79908(); # stampe 79907

A partire da Perl 5.22, questo comportamento difettoso, pur preservato per la compatibilità con le versioni precedenti, è
rilevato ed emette un avviso di deprecazione. Se vuoi che la subroutine sia in linea (con
nessun avviso), assicurarsi che la variabile non venga utilizzata in un contesto in cui potrebbe essere modificata
a parte dove è dichiarato.

# Bene, nessun avviso
INIZIO {
mio $x = 54321;
*INLINED = sub() { $x };
}
# Avverte. Le future versioni di Perl smetteranno di incorporarlo.
INIZIO {
mio $x;
$ x = 54321;
*ALSO_INLINED = sub() { $x };
}

Perl 5.22 introduce anche l'attributo sperimentale "const" come alternativa. (Disattivare
gli avvisi "sperimentale::const_attr" se si desidera utilizzarlo.) Quando applicato a un
subroutine anonima, forza la chiamata del sub quando l'espressione "sub" è
valutato. Il valore restituito viene catturato e trasformato in una subroutine costante:

mio $x = 54321;
*INLINED = sub: const { $x };
$x++;

Il valore restituito di "INLINED" in questo esempio sarà sempre 54321, indipendentemente dal successivo
modifiche a $x. Puoi anche inserire qualsiasi codice arbitrario all'interno del sub, come sarà
eseguito immediatamente e il suo valore restituito viene acquisito allo stesso modo.

Se vuoi davvero una subroutine con un prototipo "()" che restituisce una variabile lessicale tu
può facilmente forzarlo a non essere in linea aggiungendo un "ritorno" esplicito:

INIZIO {
mio $x = 79907;
*RT_79908 = sub() { restituisce $x };
$x++;
}
stampa RT_79908(); # stampe 79908

Il modo più semplice per sapere se una subroutine era inline è usare B::Deparse. Considera questo
esempio di due subroutine che restituiscono 1, una con un prototipo "()" che lo fa essere
inline e uno senza (con output deparse troncato per chiarezza):

$ perl -MO=Deparse -le 'sub ONE { 1 } if (ONE) { print ONE if ONE }'
sotto UNO {
1;
}
se uno ) {
print UNO() se UNO ;
}
$ perl -MO=Deparse -le 'sub ONE () { 1 } if (ONE) { print ONE if ONE }'
sotto UNO () { 1 }
fare {
stampa 1
};

Se ridefinisci una subroutine che era idonea per l'inlining, riceverai un avviso da
predefinito. Puoi usare questo avviso per dire se una particolare subroutine è o meno
considerato inlineabile, poiché è diverso dall'avviso per l'override di non inline
subroutine:

$ perl -e 'sub uno () {1} sub uno () {2}'
Sottoprogramma costante uno ridefinito in -e riga 1.
$ perl -we 'sub one {1} sub one {2}'
Subroutine uno ridefinita in -e riga 1.

L'avvertimento è considerato sufficientemente grave da non essere influenzato dal -w interruttore (o il suo
assenza) perché le invocazioni della funzione precedentemente compilate continueranno a utilizzare il
vecchio valore della funzione. Se devi essere in grado di ridefinire la subroutine, devi
assicurati che non sia in linea, rilasciando il prototipo "()" (che cambia la chiamata
semantica, quindi attenzione) o ostacolando il meccanismo di inline in qualche altro modo, ad es
aggiungendo un esplicito "ritorno", come detto sopra:

sub not_inlined() { return 23 }

Override Built-in funzioni
Molte funzioni integrate possono essere sovrascritte, anche se questo dovrebbe essere provato solo occasionalmente
e per una buona ragione. In genere questo potrebbe essere fatto da un pacchetto che tenta di emulare
funzionalità integrate mancanti su un sistema non Unix.

L'override può essere eseguito solo importando il nome da un modulo in fase di compilazione--ordinario
la pre-dichiarazione non è sufficiente. Tuttavia, il pragma "use subs" ti consente, in effetti, di
predichiarare i sottotitoli tramite la sintassi di importazione e questi nomi possono quindi sovrascrivere quelli incorporati:

usa i sottotitoli 'chdir', 'chroot', 'chmod', 'chown';
chdir $da qualche parte;
subchdir { ... }

Per fare riferimento inequivocabilmente al modulo integrato, precedere il nome integrato con lo speciale
qualificatore del pacchetto "CORE::". Ad esempio, dire "CORE::open()" si riferisce sempre al
built-in "open()", anche se il pacchetto corrente ha importato qualche altra subroutine chiamata
"&open()" da un'altra parte. Anche se sembra una normale chiamata di funzione, non lo è:
il prefisso CORE:: in quel caso fa parte della sintassi di Perl e funziona per qualsiasi parola chiave,
indipendentemente da ciò che è nel pacchetto CORE. Facendo riferimento ad esso, cioè
"\&CORE::open", funziona solo per alcune parole chiave. Vedi CORE.

I moduli della libreria non dovrebbero in generale esportare nomi incorporati come "open" o "chdir" come parte
del loro elenco @EXPORT predefinito, perché potrebbero intrufolarsi nello spazio dei nomi di qualcun altro e
modificare la semantica in modo imprevisto. Invece, se il modulo aggiunge quel nome a @EXPORT_OK,
quindi è possibile per un utente importare il nome in modo esplicito, ma non implicito. Questo è,
potrebbero dire

usa il modulo 'apri';

e importerebbe l'override "aperto". Ma se hanno detto

utilizzare il modulo;

otterrebbero le importazioni predefinite senza sostituzioni.

Il precedente meccanismo di override built-in è limitato, abbastanza deliberatamente, al
pacchetto che richiede l'importazione. C'è un secondo metodo che a volte è applicabile
quando desideri sovrascrivere un built-in ovunque, senza riguardo ai limiti dello spazio dei nomi.
Ciò si ottiene importando un sottotitolo nello spazio dei nomi speciale "CORE::GLOBAL::". Qui è
un esempio che sostituisce sfacciatamente l'operatore "glob" con qualcosa che
comprende le espressioni regolari.

pacchetto REGlob;
richiedere Esportatore;
@ISA = 'Esportatore';
@EXPORT_OK = 'globo';

importazione secondaria {
il mio $pkg = turno;
ritorno a meno che @_;
my $sim = spostamento;
my $dove = ($sym =~ s/^GLOBAL_// ? 'CORE::GLOBAL' : visitatore(0));
$pkg->export($where, $sym, @_);
}

sottoglobo {
il mio $patto = turno;
il mio @go;
if (apri il mio $d, '.') {
@got = grep /$pat/, readdir $d;
chiuso $d;
}
ritorno @preso;
}
1;

Ed ecco come potrebbe essere (ab)usato:

#use REGlob 'GLOBAL_glob'; # sovrascrive glob() in TUTTI gli spazi dei nomi
pacchetto Foo;
usa REGlob 'glob'; # override glob() in Foo:: only
stampa per <^[a-z_]+\.pm\$>; # mostra tutti i moduli pragmatici

Il commento iniziale mostra un esempio artificioso, persino pericoloso. Sovrascrivendo "glob"
globalmente, si costringerebbe il nuovo (e sovversivo) comportamento per l'operatore "glob"
per ogni namespace, senza la completa conoscenza o cooperazione dei moduli che
possedere quegli spazi dei nomi. Naturalmente, questo dovrebbe essere fatto con estrema cautela, se necessario
fatto affatto.

L'esempio "REGlob" sopra non implementa tutto il supporto necessario per eseguire l'override in modo pulito
l'operatore "glob" di perl. Il "glob" integrato ha comportamenti diversi a seconda che
appare in un contesto scalare o elenco, ma il nostro "REGlob" no. Infatti, molti perl
built-in hanno tali comportamenti sensibili al contesto e questi devono essere adeguatamente supportati da
un override scritto correttamente. Per un esempio completamente funzionale di override di "glob", studia
l'implementazione di "File::DosGlob" nella libreria standard.

Quando si sostituisce un built-in, la sostituzione dovrebbe essere coerente (se possibile) con il
sintassi nativa incorporata. È possibile ottenere ciò utilizzando un prototipo adatto. Prendere il
prototipo di un built-in sovrascrivibile, usa la funzione "prototype" con un argomento di
"CORE::builtin_name" (vedi "prototype" in perlfunc).

Nota tuttavia che alcuni built-in non possono avere la loro sintassi espressa da un prototipo (come
"sistema" o "chomp"). Se li sovrascrivi non sarai in grado di imitarli completamente
sintassi originale.

Anche le funzioni integrate "do", "require" e "glob" possono essere sovrascritte, ma a causa di una magia speciale,
la loro sintassi originale è preservata e non è necessario definire un prototipo per loro
sostituzioni. (Tuttavia, non puoi sovrascrivere la sintassi "do BLOCK").

"richiedere" ha una speciale magia oscura aggiuntiva: se invochi la tua sostituzione "richiesta" come
"require Foo::Bar", riceverà effettivamente l'argomento "Foo/Bar.pm" in @_. Vedere
"richiedere" in perlfunc.

E, come avrai notato dall'esempio precedente, se sovrascrivi "glob", il "<*>"
anche l'operatore glob viene sovrascritto.

In modo simile, sovrascrivere la funzione "readline" sovrascrive anche l'equivalente I/O
operatore" ". Inoltre, sovrascrivendo "readpipe" si sovrascrive anche gli operatori "``"
e "qx//".

Infine, alcuni built-in (es. "exists" o "grep") non possono essere sovrascritti.

Caricamento automatico
Se chiami una subroutine che non è definita, normalmente otterresti un immediato, fatale
errore che lamenta che la subroutine non esiste. (Allo stesso modo per le subroutine in uso
come metodi, quando il metodo non esiste in nessuna classe base del pacchetto della classe.)
Tuttavia, se una subroutine "AUTOLOAD" è definita nel pacchetto o nei pacchetti utilizzati per individuare
la subroutine originale, quindi quella subroutine "AUTOLOAD" viene chiamata con gli argomenti che
sarebbe stato passato alla subroutine originale. Il nome completo del
la subroutine originale appare magicamente nella variabile globale $AUTOLOAD dello stesso pacchetto
come routine "AUTOLOAD". Il nome non viene passato come argomento ordinario perché, ehm,
beh, solo perché, ecco perché. (Come eccezione, una chiamata di metodo a un "import" inesistente
o il metodo "unimport" viene semplicemente ignorato. Inoltre, se la subroutine AUTOLOAD è un
XSUB, ci sono altri modi per recuperare il nome della subroutine. Vedere "Caricamento automatico con XSUB"
in perlguts per i dettagli.)

Molte routine "AUTOLOAD" caricano una definizione per la subroutine richiesta usando eval (),
quindi esegui quella subroutine usando una forma speciale di vai a() che cancella lo stack frame di
la routine "AUTOLOAD" senza lasciare traccia. (Vedi la fonte del modulo standard documentato
in AutoLoader, per esempio.) Ma una routine "AUTOLOAD" può anche solo emulare la routine
e non definirlo mai. Ad esempio, supponiamo che una funzione che non è stata definita
dovrebbe semplicemente invocare "sistema" con quegli argomenti. Tutto quello che faresti è:

sotto CARICAMENTO AUTOMATICO {
mio $programma = $AUTOLOAD;
$programma =~ s/.*:://;
sistema($programma, @_);
}
Data();
chi sono');
ls('-l');

In effetti, se predichiari le funzioni che vuoi chiamare in quel modo, non hai nemmeno bisogno
parentesi:

usa subs qw(data chi ls);
Data;
chi sono";
ls '-l';

Un esempio più completo di questo è il modulo Shell su CPAN, che può trattare undefined
chiamate di subroutine come chiamate a programmi esterni.

Sono disponibili meccanismi per aiutare gli autori dei moduli a dividere i propri moduli in caricabili automaticamente
File. Vedere il modulo AutoLoader standard descritto in AutoLoader e in AutoSplit, il
moduli SelfLoader standard in SelfLoader e il documento sull'aggiunta di funzioni C a Perl
codice in perlxs.

Sottoprogramma Attributi
Una dichiarazione o definizione di subroutine può avere un elenco di attributi ad essa associati.
Se tale elenco di attributi è presente, viene suddiviso in corrispondenza dei confini dello spazio o dei due punti e
trattato come se fosse stato visto un "attributo d'uso". Vedi gli attributi per i dettagli su cosa
gli attributi sono attualmente supportati. A differenza della limitazione con l'"uso" obsoleto
attrs", la sintassi "sub : ATTRLIST" funziona per associare gli attributi a un pre-
dichiarazione, e non solo con una definizione di subroutine.

Gli attributi devono essere validi come semplici nomi identificativi (senza alcuna punteggiatura altro
rispetto al carattere '_'). Potrebbero avere un elenco di parametri aggiunto, che è solo selezionato
per sapere se le sue parentesi ('(',')') nidificano correttamente.

Esempi di sintassi valida (anche se gli attributi sono sconosciuti):

sub fnord (&\%) : switch(10,foo(7,3)) : costoso;
sub plugh() : Ugly('\(") :Bad;
subxyzzy : _5x5 { ... }

Esempi di sintassi non valida:

sub fnord : switch(10,foo(); # ()-string non bilanciata
sub snoid : Ugly('('); # ()-string non bilanciata
sub xyzzy : 5x5; # "5x5" non è un identificatore valido
sub plugh : Y2::nord; # "Y2::nord" non è un semplice identificatore
sub snurt: pippo + bar; # "+" non i due punti o lo spazio

L'elenco degli attributi viene passato come elenco di stringhe costanti al codice che associa
loro con il sottoprogramma. In particolare, il secondo esempio di sintassi valida sopra
attualmente si presenta così in termini di come viene analizzato e invocato:

usa gli attributi __PACKAGE__, \&plugh, q[Ugly('\(")], 'Bad';

Per ulteriori dettagli sugli elenchi di attributi e sulla loro manipolazione, vedere attributi e
Attributo:: Gestori.

Utilizzare perlsub online utilizzando i servizi onworks.net



Gli ultimi programmi online per Linux e Windows