
perlfunc - Le funzioni integrate in Perl

Le funzioni in questa sezione possono comparire come termini in una espressione. Esse cadono in due categorie principali: operatori di lista e operatori unari con nome. La differenza consiste nella relazione di precedenza con una virgola che segue. (Consultate la tabella delle precedenze in perlop). Gli operatori di lista prendono più di un argomento, mentre gli operatori unari non accettano mai più di un argomento. Quindi, la virgola termina l'argomento di un operatore unario, ma separa semplicemente gli argomenti di un operatore di lista. Un operatore unario solitamente fornisce un contesto scalare al suo argomento, mentre un operatore di lista può conferire sia un contesto scalare che uno di lista ai suoi argomenti. Se conferisce entrambi i contesti, allora gli argomenti scalari verranno per primi, seguiti dall'argomento lista. (Va notato che ci può essere uno solo di tali argomenti). Per esempio, splice() ha tre argomenti scalari seguiti da una lista, mentre gethostbyname() ha quattro argomenti scalari.
Nelle descrizioni della sintassi che seguono, gli operatori di lista che si aspettano una lista (e che forniscono un contesto di lista agli elementi della lista) vengono mostrati con LISTA come argomento. Tale lista può essere costituita da una combinazione qualunque di argomenti scalari o valori di lista; i valori di lista saranno inclusi nella lista come se ogni singolo elemento fosse interpolato in quel punto, formando un valore di lista unico, più lungo. Delle virgole dovrebbero separare gli elementi della LISTA.
Ogni funzione dell'elenco sottostante può essere usata o meno con parentesi attorno ai propri argomenti. (La descrizione della sintassi omette le parentesi). Se usate le parentesi, la semplice regola (benché talvolta sorprendente) è questa: sembra una funzione, dunque è una funzione, e la precedenza non importa. Altrimenti è un operatore di lista o un operatore unario, e allora la precedenza conta. Ed uno spazio vuoto tra la funzione e la parentesi aperta non conta, quindi a volte dovete stare attenti:
print 1+2+4; # Stampa 7. print(1+2) + 4; # Stampa 3. print (1+2)+4; # Anche questo stampa 3! print +(1+2)+4; # Stampa 7. print ((1+2)+4); # Stampa 7.
Se lanciate Perl con lo switch -w, allora vi può avvertire a questo proposito. Per esempio, la terza linea produce:
print (...) interpreted as function at - line 1.
Useless use of integer addition in void context at - line 1
[print (...) è interpretato come funzione alla linea 1. Utilizzo inutile di una addizione intera in un contesto vuoto alla linea 1, NdT]
Un esiguo numero di funzioni non accetta alcun argomento, e quindi non funziona né come operatore di lista né come operatore unario. Sono incluse in questo gruppo funzioni come time e endpwent. Per esempio, time+86_400 vuol dire sempre time() + 86_400.
Per le funzioni che possono essere usate in un contesto scalare o di lista, un fallimento non bloccante viene generalmente indicato restituendo il valore indefinito in un contesto scalare, e la lista nulla in un contesto di lista.
Ricordate la seguente importante regola: Non esiste alcuna regola che correla il comportamento di un'espressione in un contesto di lista al suo comportamento in un contesto scalare, o viceversa. Potrebbe comportarsi in due maniere totalmente differenti. Ogni operatore e ogni funzione decidono quale genere di valore sia più appropriato restituire in un contesto scalare. Alcuni operatori restituiscono la lunghezza della lista che sarebbe stata restituita in un contesto di lista. Alcuni operatori restituiscono il primo valore nella lista. Alcuni restituiscono l'ultimo. Alcuni operatori restituiscono il conto delle operazioni eseguite con successo. In generale, fanno quello che volete, a meno che non vogliate la consistenza.
Un array dotato di nome, in un contesto scalare è piuttosto differente da quella che a prima vista potrebbe apparire come una lista in un contesto scalare. Non potete fare in modo che una lista come (1,2,3) si trovi in un contesto scalare, poiché il compilatore conosce il contesto al momento della compilazione. Genererebbe l'operatore scalare virgola, non l'operatore virgola che costruisce una lista. Ciò significa che quella non era una lista nemmeno in partenza.
In generale, le funzioni Perl che fungono da wrapper [involucro, interfaccia tra un programma ed un altro, NdT] per le chiamate di sistema che hanno lo stesso nome (come chown(2), fork(2), closedir(2), ecc.) restituiscono tutte vero quando hanno successo e undef in caso contrario, come viene solitamente menzionato nelle descrizioni che seguono. Ciò differisce dall'interfaccia C, che restituisce -1 in caso di fallimento. Le eccezioni a questa regola sono wait, waitpid e syscall. Le chiamate di sistema inoltre impostano la variabile speciale $! in caso di fallimento. Altre funzioni non lo fanno, se non accidentalmente.
Ecco le funzioni del Perl (incluse certe cose che assomigliano a funzioni, come alcune parole chiave e operatori dotati di nome) ordinate per categoria. Alcune funzioni appaiono in più di una posizione.
chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q/STRINGA/, qq/STRINGA/, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///
m//, pos, quotemeta, s///, split, study, qr//
abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand
pop, push, shift, splice, unshift
grep, join, map, qw/STRINGA/, reverse, sort, unpack
delete, each, exists, keys, values
binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, rewinddir, seek, seekdir, select, syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write
pack, read, syscall, sysread, syswrite, unpack, vec
-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, sysopen, umask, unlink, utime
caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray
caller, import, local, my, our, package, use
defined, dump, eval, formline, local, my, our, reset, scalar, undef, wantarray
alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx/STRINGA/, setpgrp, setpriority, sleep, system, times, wait, waitpid
do, import, no, package, require, use
bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use
accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair
msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite
endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, getlogin, getpwent, getpwnam, getpwuid, setgrent, setpwent
endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnetbyaddr, getnetbyname, getnetent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent, setnetent, setprotoent, setservent
gmtime, localtime, time, times
abs, bless, chomp, chr, exists, formline, glob, import, lc, lcfirst, map, my, no, our, prototype, qx, qw, readline, readpipe, ref, sub*, sysopen, tie, tied, uc, ucfirst, untie, use
* - sub era una parola chiave in perl4, ma in perl5 è un operatore, che può essere usato nelle espressioni.
dbmclose, dbmopen
Perl è nato su Unix e dunque può accedere a tutte le normali chiamate di sistema Unix. In ambienti non-Unix, le funzionalità di alcune di queste chiamate potrebbe non essere disponibile, oppure i dettagli potrebbero essere un po' diversi. Le funzioni Perl influenzate da questo aspetto sono:
-X, binmode, chmod, chown, chroot, crypt, dbmclose, dbmopen, dump, endgrent, endhostent, endnetent, endprotoent, endpwent, endservent, exec, fcntl, flock, fork, getgrent, getgrgid, gethostbyname, gethostent, getlogin, getnetbyaddr, getnetbyname, getnetent, getppid, getpgrp, getpriority, getprotobynumber, getprotoent, getpwent, getpwnam, getpwuid, getservbyport, getservent, getsockopt, glob, ioctl, kill, link, lstat, msgctl, msgget, msgrcv, msgsnd, open, pipe, readlink, rename, select, semctl, semget, semop, setgrent, sethostent, setnetent, setpgrp, setpriority, setprotoent, setpwent, setservent, setsockopt, shmctl, shmget, shmread, shmwrite, socket, socketpair, stat, symlink, syscall, sysopen, system, times, truncate, umask, unlink, utime, wait, waitpid
Per maggiori informazioni riguardanti la portabilità di queste funzioni, consultate perlport ed altra documentazione disponibile specifica per una data piattaforma.
Un test sul file, dove X è una delle lettere elencate di seguito. Questo operatore unario opera su un argomento, o un nome di file o un filehandle, e controlla il file associato per verificare la verità di una condizione. Se si omette l'argomento, utilizza il valore corrente di $_; fa eccezione -t, che utilizza STDIN. A meno di indicazione contraria, restituisce 1 per indicare la verità della condizione verificata, e '' in caso di falsità, mentre restituisce un valore non definito se il file non esiste. A dispetto della stranezza dei nomi, valgono le stesse regole di precedenza di ogni altro operatore unario, e l'argomento può essere racchiuso fra parentesi come per qualsiasi altro operatore. L'operatore può essere uno qualsiasi fra quelli seguenti:
-r Il file e` leggibile da parte del uid/gid effettivo.
-w Il file e` scrivibile da parte del uid/gid effettivo.
-x Il file e` eseguibile da parte del uid/gid effettivo.
-o Il file appartiene al uid effettivo.
-R Il file e` leggibile da parte del uid/gid reale.
-W Il file e` scrivibile da parte del uid/gid reale.
-X Il file e` eseguibile da parte del uid/gid reale.
-O Il file appartiene al uid reale.
-e Il file esiste.
-z Il file ha dimensione zero (e` vuoto).
-s Il file ha dimensione diversa da zero (restituisce la dimensione in byte).
-f Il file e` un file vero e proprio [non una directory ma un link, NdT]
-d Il file e` una directory.
-l Il file e` un link simbolico.
-p Il file e` una named pipe (FIFO), o la Filehandle e` una pipe.
-S Il file e` un socket.
-b Il file e` un file speciale per una periferica a blocchi.
-c Il file e` un file speciale per una periferica a caratteri.
-t La filehandle e` aperta su una tty [per esempio un terminale, NdT].
-u Il file ha il bit setuid impostato.
-g Il file ha il bit setgid impostato.
-k Il file ha lo sticky bit impostato.
-T Il file contiene un testo ASCII (viene determinato in maniera euristica).
-B Il file e` un file binario (opposto di -T).
-M Orario di avvio dello script meno l'orario di ultima modifica del file, in giorni.
-A Come sopra, ma con l'orario di ultimo accesso al file.
-C Come sopra, ma per l'orario di ultima modifica del inode (su Unix, potrebbe essere diverso su un'altra piattaforma).
Esempio:
while (<>) {
chomp;
next unless -f $_; # ignora i file speciali
#...
}
L'interpretazione degli operatori che verificano i permessi dei file -r, -R, -w, -W, -x e -X è basata di default solamente sullo stato del file e sul valore degli uid e gid dell'utente. Ci potrebbero essere altre ragioni per cui vi potrebbe risultare impossibile leggere, scrivere o eseguire il file. Tali ragioni potrebbero essere ad esempio controlli di accesso su un filesystem di rete, ACL (Access Control lists, [liste di controllo di accesso, NdT]), filesystem accessibili in sola lettura, e formati eseguibili non riconosciuti.
Va notato inoltre che, per il superuser sui filesystem locali, gli operatori -r, -R, -w e -W restituiscono sempre 1, e -x e -X restituiscono 1 se uno qualsiasi dei bit di esecuzione è impostato. Gli script eseguiti dal superuser devono perciò utilizzare la funzione stat() per determinare il reale stato del file, oppure devono temporaneamente impostare il loro uid effettivo ad un valore diverso.
Se state usando le ACL, c'è una direttiva chiamata filetest che può produrre risultati più accurati di quelli ottenibili con un semplice stat(). Con la direttiva use filetest 'access' in uso, gli operatori sopra citati verificheranno i permessi utilizzando la famiglia di chiamate a sistema operativo access(). Va notato inoltre che quando questa direttiva è in uso, gli operatori -x e -X potrebbero restituire il valore booleano vero anche se i bit di esecuzione non sono impostati sui file (così come potrebbe accadere anche se nessun ulteriore permesso di eseguibilità è stato garantito da una ACL). Queste stranezze sono dovute alle definizioni del sistema operativo su cui operano. Leggete la documentazione di filetest per avere maggiori informazioni.
Va notato che -s/a/b/ non è la negazione di una sostituzione. Scrivere -exp($pippo) funziona sempre come ci si aspetta che faccia, solo le lettere singole che seguono un segno meno sono interpretate come test sui file.
Gli operatori -T e -B funzionano nel modo seguente. Il primo blocco (più o meno) del file viene esaminato alla ricerca di caratteri strani come ad esempio codici di controllo o caratteri con il bit alto impostato. Se vengono individuati troppi caratteri strani (>30%), l'operatore -B restituisce vero; altrimenti restituirà vero l'operatore -T. Inoltre, un qualunque file che contiene un carattere "null" nel primo blocco è considerato binario. Se -T o -B vengono usati su un filehandle, viene esaminato il buffer di IO corrente, e non il primo blocco. Sia -T che -B restituiscono il valore booleano vero su un file vuoto, o su un filehandle che è arrivata alla fine del file. Poiché eseguendo -T deve avvenire una lettura del file, nella maggior parte delle occasioni ha senso eseguire un -f sul file come prima cosa, come ad esempio in next unless -f $file && -T $file.
Se a uno qualsiasi dei test sui file (o uno fra gli operatori stat e lstat) viene richiesto di esaminare lo speciale filehandle costituito da un trattino di sottolineatura "_", verrà utilizzata il risultato della chiamata stat effettuata dall'ultimo test sul file o operatore stat, in modo da risparmiare una chiamata a sistema operativo. (Questo non vale per -t, e dovrete ricordare anche che lstat() e -l memorizzeranno il risultato della chiamata stat relative al link simbolico stesso, e non quelle relative al file puntato dal link). (Inoltre, se il buffer della chiamata stat è stato precedentemente riempito da una chiamata lstat, -T e -B verranno reimpostati al valore restituito da stat _). Esempio:
print "Si puo` fare.\n" if -r $a || -w _ || -x _;
stat($filename);
print "Leggibile\n" if -r _;
print "Scrivibile\n" if -w _;
print "Eseguibile\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;
print "Sticky\n" if -k _;
print "Testo\n" if -T _;
print "File binario\n" if -B _;
Restituisce il valore assoluto del suo argomento. Se VALORE viene omesso, abs() usa $_.
Accetta una connessione in entrata su un socket, proprio come fa la chiamata di sistema accept(2). Se ha successo restituisce l'indirizzo compattato, falso altrimenti. Date un'occhiata all'esempio in "Sockets: Client/Server Communication" in perlipc ["Socket: Comunicazione Client/Server", NdT].
Su sistemi che, sui file, supportano un flag chiuso-su-esecuzione, tale flag sarà impostato per il più recente descrittore di file aperto, come stabilito dal valore di $^F. Consultate "$^F" in perlvar.
Fa in modo che un SIGALARM sia inviato a questo processo dopo che è trascorso il numero di secondi indicato. Se SECONDI non viene specificato, viene utilizzato il valore memorizzato in $_. (Su alcune macchine, sfortunatamente, il tempo trascorso può essere inferiore o superiore fino a un secondo rispetto al numero specificato a causa del sistema con cui vengono contati i secondi, e lo scheduling [programmazione, NdT] dei processi può ulteriormente ritardare la consegna del segnale).
Può essere in esecuzione un solo timer alla volta. Ciascuna chiamata disabilita il timer definito in precedenza, ed un argomento di 0 può essere fornito per cancellare il timer precedente senza avviarne uno nuovo. Il valore restituito rappresenta il tempo rimanente sul timer precedente.
Per intervalli di una granularità più fine, inferiore al secondo, potete utilizzare la versione a quattro argomenti di select(), fornita da Perl, lasciando i primi tre argomenti non definiti. In alternativa potreste essere in grado di servirvi dell'interfaccia syscall per accedere a setitimer(2) se il vostro sistema supporta ciò. Anche il modulo Time::HiRes (da CPAN, e parte della distribuzione standard a partire da Perl 5.8) potrebbe risultare utile.
Solitamente è un errore mischiare chiamate alarm e sleep. (nel vostro sistema, sleep potrebbe essere essere implementata internamente con alarm)
Se volete utilizzare alarm per far scadere una chiamata di sistema, dovrete utilizzare una coppia eval/die. Non potete contare sul fatto che alarm faccia fallire la chiamata di sistema impostando $! a EINTR, poiché in alcuni sistemi Perl imposta i gestori dei segnali in modo che riavviino le chiamate di sistema. La soluzione che prevede l'uso di eval/die funziona sempre, a meno degli avvertimenti indicati in "Signals" in perlipc ["Segnali", NdT].
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n richiesto
alarm $timeout;
$nletto = sysread SOCKET, $buffer, $dimensione;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propaga gli errori inattesi
# scaduto
}
else {
# non scaduto
}
Per maggiori informazioni consultate perlipc.
Restituisce l'arcotangente di Y/X nell'intervallo da -PI a PI.
Per ottenere la tangente, potete usare la funzione Math::Trig::tan, o la consueta relazione:
sub tan { sin($_[0]) / cos($_[0]) }
Si noti che atan2(0, 0) non è ben definito.
Collega un indirizzo di rete ad un socket, proprio come fa la chiamata di sistema bind. Restituisce vero se ha successo, falso altrimenti. NOME dovrebbe essere un indirizzo compattato del tipo appropriato per il socket. Date un'occhiata agli esempi in "Sockets: Client/Server Communication" in perlipc ["Socket: Comunicazione Client/Server", NdT]..
Fa in modo che FILEHANDLE venga letto o scritto in forma "binaria" o "testuale" sui sistemi in cui le librerie run-time distinguono tra file binari e testuali. Se FILEHANDLE è un'espressione, il valore di questa viene considerato il nome del FILEHANDLE. Restituisce vero in caso di successo, altrimenti restituisce undef in ed imposta $! (errno).
Su alcuni sistemi (in generale basati su DOS e Windows) binmode() è necessario quando non state lavorando con file di testo. Per una questione di portabilità è una buona idea usarlo sempre, se richiesto, e non usarlo mai quando non è richiesto. Le persone possono anche impostare i loro input/output per essere, di default, Unicode codificato UTF-8, e non dei byte.
In altre parole: indipendentemente dal sistema operativo, usate binmode() sui file binari, come ad esempio immagini.
Se STRATO è presente, è una stringa singola, ma può contenere direttive multiple. Le direttive alternano il comportamento del filehandle. Quando STRATO è presente, usare binmode sui file di testo ha un senso.
Se STRATO viene omesso o specificato come :raw, il filehandle viene reso adatto a trasferire dati binari. Ciò include la disabilitazione di tutte le eventuali conversioni di CRLF, e la marcatura dei dati come byte (e non caratteri Unicode). Va notato che, a differenza di quanto si possa dedurre leggendo "Programming Perl" [Programmare Perl, NdT] (il libro del Cammello) o altro, :raw non è semplicemente l'inverso di :crlf, anche gli altri strati che potrebbero influire sulla natura binaria del file vengono disabilitati. Consultate PerlIO, perlrun e la discussione sulla variabile d'ambiente PERLIO.
Le direttive :bytes, :crlf, :utf8 e qualsiasi altra direttiva nella forma :..., sono chiamate strati di I/O. Per stabilire gli strati di I/O predefiniti, è possibile utilizzare la direttiva open. Si veda open.
Il parametro STRATO di binmode() è descritto come "DISCIPLINE" ["DISCIPLINA", NdT] su "Programming Perl, 3rd Edition". In ogni caso, dal momento della pubblicazione di questo libro, da molti conosciuti come il "Camel III", il consenso per quanto riguarda il nome di questa funzionalità si è spostato da "disciplina" a "strato". Tutta la documentazione di questa versione di Perl si riferisce dunque a "strato" anziché a "disciplina". Ora torniamo alla documentazione regolare...
Per marcare FILEHANDLE come UTF-8, usate :utf8.
In generale, binmode() dovrebbe essere chiamato dopo open() ma prima che qualsiasi altra operazione di I/O sia compiuta sul filehandle. Chiamare binmode() causa che tutte le operazioni di output (e forse di input) non concluse sul filehandle vengano completate. Un'eccezione a ciò è rappresentata dallo strato :encoding, che cambia la codifica predefinita di caratteri per l'handle, consultate open. A volte è necessario impostare lo strato :encoding nel mezzo delle operazioni sul filehandle ed esso non causa il completamento delle operazioni di I/O in corso. Inoltre :encoding implicitamente spinge lo strato :utf8 in cima a se stesso, dato che internamente il Perl opererà su caratteri Unicode codificati con UTF-8.
Il sistema operativo, i driver dei device, le librerie C, ed il sistema Perl a tempo di esecuzione, lavorano tutti assieme per permettere al programmatore di utilizzare un singolo carattere (\n) come terminatore di linea, indipendentemente dalla rappresentazione esterna. Su molti sistemi operativi, la rappresentazione nativa dei file di testo equivale a quella esterna, ma su alcuni sistemi la rappresentazione esterna di \n è composta da più di un carattere.
Mac OS, tutte le varianti di Unix, ed i file Stream_LF su VMS utilizzano un singolo carattere per terminare ciascuna riga nella rappresentazione esterna del testo (anche se quel singolo carattere è un CARRIAGE RETURN su Mac OS ed un LINE FEED su Unix e sulla maggior parte dei file VMS). In altri sistemi quali OS/2, DOS e le varie versioni di MS-Windows, il vostro programma vede \n come un semplice \cJ, ma ciò che in realtà viene memorizzato nei file di testo è una coppia di caratteri \cM\cJ. Ciò significa che, se non usate binmode() su tali sistemi, le sequenze che su disco sono \cM\cJ verranno convertite in \n al momento dell'input, ed ogni eventuali \n nel vostro programma verrà convertito in \cM\cJ al momento dell'output. Questo è ciò che desiderate per i file di testo, ma può rivelarsi disastroso per i file binari.
Un'altra conseguenza dell'utilizzo di binmode() è (su alcuni sistemi) rappresentata dal fatto che gli speciali delimitatori che indicano la fine del file verranno visti come parte del flusso di dati. Per i sistemi operativi della famiglia Microsoft, ciò significa che se i vostri dati binari contengono \cZ, il sottosistema di I/O considererà tale carattere come la fine del file, a meno che non usiate binmode().
binmode() non è importante solamente per le operazioni readline() e print(), ma anche quando si utilizzano read(), seek(), sysread(), syswrite() e tell() (consultate perlport per ulteriori dettagli). Date un'occhiata alle variabili $/ e $\ in perlvar per capire come fare ad impostare manualmente le vostre sequenze di terminatori di linea per l'input e l'output.
La funzione dice al qualcosa referenziato da RIF che ora è un oggetto nel package NOMECLASSE. Se NOMECLASSE viene omesso, viene usato il package corrente. Visto che un bless [letteralmente benedizione, consacrazione, NdT] è spesso l'ultima cosa in un costruttore, restituisce per convenienza il riferimento. Usate sempre la versione a due argomenti se una classe derivata potrebbe ereditare la funzione che effettua il bless. consultate perltoot e perlobj per maggiori dettagli sull'operazione di bless (e i blessing) degli oggetti.
Prendete sempre in considerazione il fatto di effettuare il bless di oggetti nelle NOMECLASSE che utilizzano sia maiuscole che minuscole. I namespace con tutte le lettere minuscole sono considerati riservati per le direttive del Perl. I tipi interni hanno tutti i nomi maiuscoli. Per prevenire la confusione, potete pure evitare tali nomi di package. Assicuratevi che NOMECLASSE sia un valore vero.
Consultate "Perl Modules" in perlmod ["Moduli Perl", NdT].
Restituisce il contesto del chiamante della subroutine corrente. In un contesto scalare, restituisce il nome del package del chiamante se tale chiamante esiste, ovvero, se ci troviamo in una subroutine oppure eval o require, altrimenti il valore indefinito. In un contesto di lista, restituisce
($package, $nomefile, $linea) = caller;
Con ESPR, restituisce dell'informazione addizionale che il debugger utilizza per stampare una traccia dello stack. Il valore di ESPR indica quanti record di attivazione risalire prima di quello corrente.
($package, $nomefile, $linea, $subroutine, $ha_argomenti,
$voglio_array, $testo_eval, $e_richiesto, $indicazioni, $maschera_di_bit) = caller($i);
Qui, a $subroutine può essere applicato (eval) se il record non è una subroutine ma un eval. In questo caso, vengono impostati elementi addizionali quali $testo_eval e $e_richiesto: $e_richiesto è vero se il record è creato da un'istruzione require o use, $testo_eval contiene il testo dell'istruzione eval ESPR. In particolare, per un'istruzione eval BLOCCO, a $filename è applicato (eval), ma $testo_eval è indefinito. (Va notato anche che ogni istruzione use crea un record require all'interno di un record eval ESPR. A $subroutine può anche essere applicato (sconosciuto) se a questa particolare subroutine capita di essere cancellata dalla tabella dei simboli. $ha_argomenti è vero se viene impostata una nuova istanza di @_ per il record. $indicazioni e $maschera_di_bit contengono indicazioni prammatiche che sono state utilizzate per compilare il chiamante. I valori $indicazioni e $maschera_di_bit sono soggetti a cambiamenti fra le versioni del Perl e non sono intese per l'uso esterno.
Inoltre, quando viene chiamato all'interno del package DB, il chiamante restituisce informazioni più dettagliate: esso imposta la variabile di lista @DB::args per essere gli argomenti con i quali la subroutine è stata invocata.
Siate consapevoli che l'ottimizzatore potrebbe avere ottimizzato a parte i record di attivazione, prima che il chiamante abbia una possibilità di ottenere l'informazione. Questo significa che chiamante(N) potrebbe non restituire l'informazione che riguarda il record di attivazione che vi aspettate di ottenere per N > 1. In particolare, @DB::args potrebbe avere l'informazione dalla volta precedente che caller è stato chiamato.
Cambia la directory corrente facendola diventare ESPR, se possibile. Se ESPR viene omessa, cambia la directory corrente in quella specificata in $ENV{HOME}, se impostata; altrimenti, cambia la directory corrente in quella specificata in $ENV{LOGDIR}. (Sotto VMS, viene controllata anche la variabile $ENV{SYS$LOGIN}). Se nessuna di queste variabili è impostata, chdir non ha alcun effetto. Restituisce vero in caso di successo, falso negli altri casi. Consultate l'esempio in die.
Su sistemi che supportano fchdir, potreste passare come argomenti un file handle oppure un directory handle. Su sistemi che non supportano fchdir, passare gli handle produce un errore fatale a tempo di esecuzione.
Cambia i permessi di una lista di file. Il primo elemento della lista deve essere la modalità numerica, che deve probabilmente essere un numero ottale, e che sicuramente non deve essere una stringa di cifre ottali: 0644 va bene, '0644' no. Restituisce il numero di file modificati con successo. Consultate anche "oct", se tutto ciò che avete a disposizione è una stringa.
$cnt = chmod 0755, 'pippo', 'pluto';
chmod 0755, @eseguibili;
$modalita = '0644'; chmod $modalita, 'pippo'; # !!! imposta la modalita` a
# --w----r-T
$modalita = '0644'; chmod oct($modalita), 'pippo'; # questo e` meglio
$modalita = 0644; chmod $modalita, 'pippo'; # questo e` il migliore
Su sistemi che supportano fchmod, potreste passare i file handle tra i file. Su sistemi che non supportano fchmod, passare file handle produce un errore fatale a tempo di esecuzione.
open(my $fh, "<", "pippo");
my $perm = (stat $fh)[2] & 07777;
chmod($perm | 0600, $fh);
Potete anche importare le costanti simboliche S_I* dal modulo Fcntl:
use Fcntl ':mode';
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @eseguibili;
# Questo e` identico al chmod 0755 dell'esempio sopra.
Questa versione più intelligente di "chop" rimuove dalla coda della stringa passata come parametro qualsiasi stringa che corrisponda al valore corrente di $/ (conosciuta anche come $INPUT_RECORD_SEPARATOR [record separatore di input, NdT] nel modulo English). La funzione restituisce il numero totale di caratteri rimossi da tutti i suoi argomenti. È spesso utilizzato per rimuovere il newline dalla fine di un record in input, quando temete che il record possa essere sprovvisto del suo newline. Quando è utilizzata in paragraph mode [modalità paragrafo, NdT] ($/ = ""), rimuove tutti i newline in coda ad una stringa. Quando è utilizzata in slurp mode [modalità slurp, NdT] ($/ = undef) o con una lunghezza di record fissa ($/ è un riferimento ad un intero o a qualcosa di simile, consultate perlvar), chomp() non rimuoverà nulla. Se VARIABILE viene omessa, chomp agisce su $_. Ad esempio:
while (<>) {
chomp; # rimuove \n dall'ultimo campo
@array = split(/:/);
# ...
}
Se VARIABILE è un hash, chomp() agisce sui valori dell'hash, ma non sulle sue chiavi.
Potete utilizzare chomp su qualsiasi cosa che sia un lvalue [valore a sinistra di un'espressione, NdT], incluso un assegnamento:
chomp($cwd = `pwd`);
chomp($risposta = <STDIN>);
Se usate chomp() su una lista, viene effettuato il chomp di ogni elemento, e viene restituito il numero totale di caratteri rimossi.
Se la direttiva encoding è nello scope, allora le lunghezze che vengono restituite sono calcolate a partire dalla lunghezza di $/ in caratteri Unicode che non è sempre la stessa cosa della lunghezza di $/ nella codifica nativa.
Va notato che le parentesi sono necessarie quando usate chomp() su qualsiasi cosa che non sia una variabile semplice. Ciò deriva dal fatto che chomp $cwd = `pwd`; è interpretato come (chomp $cwd) = `pwd`;, anziché come chomp( $cwd = `pwd` ), come vi potreste aspettare. Similmente, chomp $a, $b è interpretato come chomp($a), $b anziché come chomp($a, $b).
Taglia via l'ultimo carattere di una stringa e restituisce il carattere tagliato. È molto più efficiente di s/.$//s perché non scandisce né copia la stringa. Se VARIABILE viene omessa, taglia $_. Se VARIABILE è un hash, taglia i valori dell'hash, ma non le sue chiavi.
Potete utilizzare chop su qualsiasi cosa che sia un lvalue [valore a sinistra di un'espressione, NdT], incluso un assegnamento.
Chiamando chop su una lista, ogni elemento viene tagliato. Viene restituito solo il valore dell'ultimo chop effettuato.
Va notato che chop restituisce l'ultimo carattere. Per ottenere tutto tranne l'ultimo carattere, utilizzate substr($stringa, 0, -1).
Si veda anche "chomp".
Cambia il proprietario (ed il gruppo) di una lista di file. I primi due elementi della lista devono essere uid e gid numerici, nell'ordine indicato. Un valore di -1 in una di queste due posizioni viene interpretato dalla maggior parte dei sistemi operativi come volontà di non alterare tale valore. Restituisce il numero di file modificati con successo.
$cnt = chown $uid, $gid, 'pippo', 'pluto';
chown $uid, $gid, @nomifile;
Su sistemi che supportano fchown, potreste passare i file handle tra i file. Su sistemi che non supportano fchmod, passare file handle produce un errore fatale a tempo di esecuzione.
Di seguito è riportato un esempio che risolve le uid non numeriche servendosi del file passwd:
print "Utente: ";
chomp($utente = <STDIN>);
print "File: ";
chomp($pattern = <STDIN>);
($login,$pass,$uid,$gid) = getpwnam($utente)
or die "$utente non e` presente nel file passwd";
@ary = glob($pattern); # espande i nomi dei file
chown $uid, $gid, @ary;
Sulla maggior parte dei sistemi, non è consentito cambiare il proprietario dei file a meno che non si sia superuser. Dovreste tuttavia essere in grado di cambiare il gruppo impostandolo ad uno qualsiasi dei vostri gruppi secondari. Su sistemi non sicuri, queste restrizioni potrebbero essere meno rigide, ma assumere una cosa del genere non è portabile. Sui sistemi POSIX, potete verificare questa condizione in questo modo:
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
$chown_possibile = not sysconf(_PC_CHOWN_RESTRICTED);
Restituisce il carattere rappresentato da NUMERO nell'insieme dei caratteri. Ad esempio, chr(65) è "A" sia in ASCII che in Unicode, e chr(0x263a) è una faccina sorridente in Unicode. Va notato che i caratteri da 127 a 255 (inclusi) di default non sono codificati in Unicode per ragioni di compatibilità all'indietro (ma consultate encoding).
Se NUMERO viene omesso, utilizza $_.
Per l'inverso di questa funzione, utilizzate "ord".
Va notato che mediante la direttiva bytes, il NUMERO viene mascherato dagli otto bit bassi.
Consultate perlunicode e encoding per maggiori informazioni su Unicode.
Questa funzione funziona come la omonima chiamata di sistema: rende la directory data come nuova directory principale per tutti i percorsi che cominciano con un /, per il vostro processo e tutti i suoi figli (Non cambia la vostra directory corrente, che non viene modificata). Per motivi di sicurezza, questa chiamata è riservata al superuser. Se NOMEFILE viene omesso, esegue un chroot su $_.
Chiude il file o la pipe associata con il filehandle, restituisce vero solo se i buffer di IO sono stati svuotati con successo e chiude il descrittore di file di sistema. Se l'argomento viene omesso, chiude il filehandle correntemente selezionato.
Non è necessario che voi chiudiate il FILEHANDLE se immediatamente andrete a fare un'altra open sul filehandle perché open lo chiuderà per voi. (Si veda open). Ad ogni modo, un'esplicita close su di un file di input riazzererà il contatore di linea ($.), mentre non lo farà la close implicita fatta da open.
Se il filehandle proviene da una open su pipe, close restituirà in aggiunta falso se fallisce una delle altre chiamate di sistema coinvolte, oppure se il programma esce con uno stato non-zero. (Se il solo problema è che il programma sia uscito come non-zero, $! verrà impostato a 0). Anche chiudere una pipe fa attendere che il processo in esecuzione su quella pipe sia completato, nel caso vogliate esaminare successivamente l'output della pipe, e implicitamente pone in $? il valore di stato dell'uscita di quel comando.
Chiudere prematuramente la lettura finale di una pipe (cioè prima che il processo che sta scrivendo su di essa dall'altra estremità l'abbia chiusa) si risolverà in una SIGPIPE che verrà recapitata a chi sta scrivendo. Se l'altra estremità non può occuparsene, ci si assicuri di leggere tutti i dati prima di chiudere la pipe.
Esempio:
open(OUTPUT, '|sort >pippo') # pipe da ordinare
or die "Non posso avviare sort: $!";
#... # stampo qualcosa in output
close OUTPUT # aspetto che il sort termini
or warn $! ? "Errore nel chiudere la sort del pipe: $!"
: "Stato di uscita $? dal sort";
open(INPUT, 'pippo') # ricevo i risultati di sort
or die "Non posso aprire 'pippo' per l'input: $!";
FILEHANDLE può essere un'espressione i cui valori possono essere usati come un filehandle indiretto, solitamente il nome effettivo del filehanlde.
Chiude una directory aperta da opendir e restituisce l'esito di quella chiamata di sistema.
Tenta di connettersi ad un socket remoto, proprio come fa la chiamata di sistema connect. Restituisce vero se ha successo, falso altrimenti. NOME dovrebbe essere un indirizzo compattato del tipo appropriato per il socket. Date un'occhiata gli esempi in "Sockets: Client/Server Communication" in perlipc ["Socket: Comunicazione Client/Server", NdT].
continue in realtà è un'istruzione per il controllo di flusso piuttosto che una funzione. Se c'è un continue BLOCCO associato ad un BLOCCO (generalmente in un while o in un foreach), questo viene eseguito appena prima che la condizione venga valutata nuovamente, come la terza parte di un ciclo for in C. Può quindi essere utilizzato per incrementare un contatore, anche se il ciclo viene proseguito con l'istruzione next (che è simile alla funzione continue del C).
last, next o redo possono apparire in un blocco continue. last e redo si comporteranno come se fossero stati eseguiti dal blocco principale. Così farà anche next, ma poiché questo eseguirà a sua volta un blocco continue, i risultati potrebbero essere molto divertenti.
while (ESPR) {
### redo porta sempre qui
fai_qualcosa;
} continue {
### next porta sempre qui
fai_qualcos_altro;
# e di nuovo all'inizio del ciclo per valutare ESPR
}
### last porta sempre qui
Omettere la sezione continue è semanticamente equivalente ad utilizzarne una vuota, logico quanto basta. In questo caso, next porta direttamente alla valutazione della condizione all'inizio del ciclo.
Restituisce il coseno di ESPR (espresso in radianti). Se ESPR viene omessa, restituisce il coseno di $_.
Per l'operazione del coseno inverso, potete utilizzare la funzione Math::Trig::acos(), oppure questa relazione:
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
Crea una stringa digest [riassunto, NdT] proprio come fa la funzione crypt(3) nella libreria C (assumendo che ce ne abbiate davvero una, che non sia stata estirpata quale potenziale armamento).
crypt() è una funzione non invertibile. TESTOINCHIARO e SEME sono convertiti in una breve stringa, chiamata digest, che viene restituita. I medesimi TESTOINCHIARO e SEME restituiranno sempre la stessa stringa, ma non c'è nessun modo (conosciuto) per ottenere il TESTOINCHIARO dall'hash. Piccoli cambiamenti nel TESTOINCHIARO o nel SEME ha come risultato dei grandi cambiamenti nel digest.
Non c'è una funzione di decifratura. Questa funzione non è per nulla utile alla crittografia (per questa cosa, date un'occhiata ai moduli Crypt sul vostro mirror CPAN più vicino) e il nome "crypt" [cripta, NdT] è un po' un termine improprio. Il suo uso principale È invece quello di controllare se due parti di testo sono le stesse senza dover trasmettere o immagazzinare il testo stesso. Un esempio è controllare se viene fornita una password corretta. È il digest della password ad essere immagazzinato e non la password stessa. L'utente digita una password che viene sottoposta a crypt() con il medesimo digest memorizzato quale seme. Se i due digest corrispondono, la password è corretta.
Quando effettuate la verifica di una stringa digest esistente, dovreste usare il digest come seme (come crypt($chiaro, $digest) eq $digest). La parte SEME usata per creare il digest è visibile come parte del digest. Questo assicura che crypt() calcolerà l'hash della nuova stringa con lo stesso seme del digest. Questo fa sì che il vostro codice funzioni sia con la crypt standard che con implementazioni più esotiche. In altre parole, non presumete nulla sulla stringa restituita, o su quanti byte siano siano significativi nel digest.
Tradizionalmente, il risultato è una stringa di 13 byte: i primi due sono il seme, e sono seguiti da 11 byte appartenenti all'insieme [./0-9A-Za-z], e solo i primi otto byte della stringa digest sono significativi; tuttavia, schemi di hashing alternativi (come MD5), schemi di sicurezza di livello più elevato (come C2) ed implementazioni su piattaforme non-UNIX, possono generare stringhe diverse.
Quando scegliete un nuovo seme, create una stringa casuale di due caratteri, i quali devono appartenere all'insieme [./0-9A-Za-z] (come join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]). Questo insieme di caratteri è solo una raccomandazione; i caratteri permessi nel seme dipendono esclusivamente dalla vostra libreria crypt di sistema, e il Perl non può limitare i semi accettati da crypt().
Ecco un esempio che ci assicura che chiunque faccia girare questo programma conosca la propria password:
$pwd = (getpwuid($<))[1];
system "stty -echo";
print "Password: ";
chomp($parola = <STDIN>);
print "\n";
system "stty echo";
if (crypt($parola, $pwd) ne $pwd) {
die "Spiacente...\n";
} else {
print "ok\n";
}
Chiaramente, scrivere la vostra password a chiunque ve la richieda non è saggio.
La funzione crypt non è adatta per calcolare il valore di hash per grandi quantità di dati, non del tutto almeno, perché non potete ottenere le vostre informazioni di nuovo in chiaro. Date un'occhiata al modulo Digest per ulteriori robusti algoritmi.
Se usate crypt() su una stringa Unicode (che potenzialmente contiene caratteri con codice superiore a 255), Perl cerca di dare un senso alla situazione cercando di riportare (una copia de) la stringa ad una stringa a otto bit prima di chiamare crypt() (su quella copia). Se ciò funziona, bene. Altrimenti, crypt() termina con Wide character in crypt [crypt su carattere esteso, NdT]
[Questa funzione è stata ampiamente soppiantata dalla funzione untie].
Rompe il legame tra un file DBM ed un hash.
[Questa funzione è stata ampiamente soppiantata dalla funzione tie].
Questa funzione effettua un legame tra un file di tipo dbm(3), ndbm(3), sdbm(3), gdbm(3) oppure Berkeley DB in un hash. HASH è il nome dell'hash. (Diversamente dalla normale open, il primo argomento non è un filehandle, anche se ci assomiglia). NOMEDB è il nome del database (senza l'estensione .dir o .pag, se presente). Se il database non esiste, viene creato con una protezione specificata da MASCHERA (come modificato dalla funzione umask). Se il vostro sistema supporta solo le vecchie funzioni DBM, nel vostro programma potete effettuare solo una dbmopen. In vecchie versioni di Perl, se il vostro sistema non possedeva né DBM né ndbm, chiamare dbmopen produceva un errore bloccante; ora ciò ricade su sdbm(3).
Se non avete accesso in scrittura sul file DBM, potete solo leggere i valori dell'hash e non impostarli. Se volete testare la possibilità di scrivere, usate o i test sui file oppure tentate di impostare l'elemento di un hash fittizio all'interno di un eval che catturerà l'errore.
Va notato che le funzioni come keys e values possono restituire liste enormi quando sono usate su grandi file DBM. Potreste preferire l'uso della funzione each per iterare su grandi file DBM. Un esempio:
# stampa gli scostamenti del file history
dbmopen(%HIST,'/usr/lib/news/history',0666);
while (($chiave,$val) = each %HIST) {
print $chiave, ' = ', unpack('L',$val), "\n";
}
dbmclose(%HIST);
Consultate anche AnyDBM_File per una descrizione più generale sui pro e contro dei vari approcci dbm, come pure DB_File per una implementazione particolarmente ricca.
Potete controllare che libreria DBM state usando tramite il caricamento della libreria prima di richiamare dbmopen():
use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db")
or die "Non e` possibile aprire il file history di netscape: $!";
Restituisce un valore Booleano, che indica se ESPR ha un valore diverso dal valore indefinito undef. Se ESPR non è presente, il controllo viene fatto su $_.
Molte operazioni restituiscono undef per indicare l'insuccesso, la fine del file, un errore di sistema, una variabile non inizializzata, ed altre condizioni eccezionali. (Un semplice test Booleano non è in grado di distinguere tra undef, zero, la stringa vuota, e "0", che sono tutti ugualmente falsi). Va notato che, poiché undef è uno scalare valido, la sua presenza non indica necessariamente una condizione eccezionale: pop restituisce undef guardo il suo argomento è un array vuoto, oppure quando l'elemento da restituire è esso stesso undef.
Potete anche usare defined(&pippo) per controllare se una subroutine &pippo è stata definita in precedenza. Il valore restituito non è variato da eventuali future dichiarazioni di &pippo. Va notato che un subroutine non definita può ancora essere chiamabile: il suo package può avere un metodo AUTOLOAD che ne provoca l'esistenza la prima volta che viene chiamata, consultate perlsub.
L'uso di defined su strutture (hash ed array) è deprecato. Indicava quanta memoria era stata allocata per una determinata struttura. Questa caratteristica potrebbe scomparire nelle future versione di Perl. Al suo posto, fareste meglio ad usare un semplice test di dimensione:
if (@un_array) { print "l'array contiene elementi\n" }
if (%un_hash) { print "l'hash contiene membri\n" }
Quando utilizzato su un elemento di un hash, defined vi dice se quel valore è definito o meno, non se esiste o meno la chiave nell'hash. Usate "exists" se vi interessa la seconda informazione.
Esempi:
print if defined $switch{'D'};
print "$val\n" while defined($val = pop(@ary));
die "Non posso leggere il link $sym: $!"
unless defined($valore = readlink $sym);
sub pippo { defined &pluto ? &$pluto(@_) : die "Non esiste pluto"; }
$debugging = 0 unless defined $debugging;
Nota: Molta gente tende ad abusare di defined, e poi si sorprende di scoprire che il numero 0 e "" (la stringa di lunghezza zero) sono, in realtà, valori definiti. Per esempio, se scrivete:
"ab" =~ /a(.*)b/;
La ricerca del pattern ha successo, e $1 risulta definito, nonostante esso abbia trovato "nulla". Non è che non ha veramente trovato nulla. Piuttosto, ha trovato qualcosa che era lungo zero caratteri. Tutto ciò è piuttosto chiaro e corretto. Quando una funzione restituisce un valore indefinito, ammette di non essere in grado di fornire una risposta corretta. Quindi dovreste usare defined solo quando dubitate dell'integrità di ciò che state tentando di fare. Nelle altre circostanze, una semplice comparazione on 0 o "" è ciò che desiderate.
Data un'espressione che specifica un elemento di un hash o di un array, una porzione di hash o di array, cancella l'elemento o gli elementi specificati dall'hash o dall'array. Nel caso di un array, se gli elementi sono in fondo, la dimensione dell'array diminuirà fino al massimo elemento per il quale la condizione exists() è vera (oppure fino a 0, se tale elemento non esiste).
Restituisce una lista con lo stesso numero di elementi che si è tentato di eliminare. Ogni elemento di questa lista consiste o nel valore dell'elemento eliminato, oppure nel valore undef. In contesto scalare, questo vuol dire che il valore restituito è il valore dell'ultimo elemento eliminato (o il valore indefinito se quell'elemento non esisteva).
%hash = (pippo => 11, pluto => 22, paperino => 33);
$scalare = delete $hash{pippo}; # $scalare e` 11
$scalare = delete @hash{qw(pippo pluto)}; # $scalare e` 22
@array = delete @hash{qw(pippo pluto paperino)}; # @array e` (undef,undef,33)
Cancellare da %ENV modifica l'ambiente. Cancellare da un hash legato ad un file DBM cancella le voci dal file DBM. Cancellare da un hash o array legato potrebbe non necessariamente restituire qualcosa.
Cancellare effettivamente un elemento da un array riporta quella posizione dell'array al suo stato iniziale, non inizializzato. Successive verifiche con exists() dello stesso elemento restituiranno falso. Inoltre, cancellare elementi nel mezzo di un array non farà scorrere in basso l'indice degli elementi successivi. Usate splice() per questo. Si veda "exists".
Il seguente codice cancella (in maniera inefficiente) tutti i valori di %HASH e di @ARRAY:
foreach $chiave (keys %HASH) {
delete $HASH{$chiave};
}
foreach $indice (0 .. $#ARRAY) {
delete $ARRAY[$indice];
}
Questi fanno la stessa cosa:
delete @HASH{keys %HASH};
delete @ARRAY[0 .. $#ARRAY];
Ma entrambi risultano più lenti che l'assegnare semplicemente la lista vuota oppure rendere indefiniti %HASH o @ARRAY:
%HASH = (); # svuota completamente %HASH
undef %HASH; # dimentica che %HASH sia
# mai esistito
@ARRAY = (); # svuota completamente @ARRAY
undef @ARRAY; # dimentica che %ARRAY sia
# mai esistito
Va notato che ESPR può essere arbitrariamente complessa, purché l'operazione finale denoti l'elemento di un hash, di un array, una porzione di un hash o di un array:
delete $ref->[$x][$y]{$chiave};
delete @{$ref->[$x][$y]}{$chiave1, $chiave2, @altrechiavi};
delete $ref->[$x][$y][$indice];
delete @{$ref->[$x][$y]}[$indice1, $indice2, @altriindici];
Fuori da un eval, stampa il valore di LISTA su STDERR ed esce dal programma con il valore corrente di $! (errno). Se $! è 0, il codice di uscita è il valore di ($? >> 8) (stato del `comando` in backtick). Se ($? >> 8) è 0, esce con codice 255. All'interno di un eval(), il messaggio di errore viene memorizzato in $@ e il blocco eval viene terminato con undef come valore restituito. Questo rende die il modo di implementare una eccezione.
Esempi equivalenti:
die "Impossibile cambiare directory in spool: $!\n" unless chdir '/usr/spool/news';
chdir '/usr/spool/news' or die "Impossibile cambiare directory in spool: $!\n"
Se l'ultimo elemento di LISTA non termina con un ritorno a capo, la riga corrente dello script e la riga corrente dell'input (ove esistente) vengono stampate con un ritorno a capo in fondo. Va notato che la "riga corrente dell'input" (chiamata anche "chunk") è soggetto alla nozione di "linea" correntemente utilizzata, ed è disponibile anche nella variabile $.. Consultate "$/" in perlvar e "$." in perlvar.
Suggerimento: a volte, aggiungere ", stopped" [interrotto, NdT] al vostro messaggio può avere senso quando viene aggiunta la stringa "at pippo line 123". Supponiamo che stiate facendo girare lo script "canasta".
die "/etc/games non va bene";
die "/etc/games non va bene, interrotto";
producono, rispettivamente
/etc/games non va bene at canasta line 123.
/etc/games non va bene, interrotto at canasta line 123.
Si veda anche exit(), warn(), e il modulo Carp.
Se LISTA è vuota e $@ già contiene un valore (generalmente da un eval precedente), questo valore viene riutilizzato con l'aggiunta di un "\t...propagated" [propagato, NdT]. Può essere utile per propagare delle eccezioni:
eval { ... };
die unless $@ =~ /Expected exception/;
Se LISTA è vuota e $@ contiene un oggetto che ha un metodo PROPAGATE, questo metodo sarà chiamato con il nome del file e il numero di riga come parametri aggiuntivi. In questo caso, il valore restituito rimpiazza il valore in $@, ossia come se fosse stato chiamato <$@ = eval { $@-PROPAGATE(__FILE__, __LINE__) }; >>.
Se $@ è vuoto, viene utilizzata la stringa "Died" [terminato, NdT].
die() può anche essere chiamato con un argomento che sia un riferimento. Se questo accade all'interno di un eval(), $@ contiene quell'oggetto. Questo comportamento permette di implementare delle eccezioni più sofisticate, utilizzando degli oggetti che possono contenere dati relativi alla natura dell'eccezione. Questo schema è a volte preferibile all'utilizzo di espressioni regolari per verificare la presenza di particolari valori nella stringa $@. Ecco un esempio:
use Scalar::Util 'blessed';
eval { ... ; die Unqualche::Modulo::Eccezione->new( PIPPO => "pluto" ) };
if ($@) {
if (blessed($@) && $@->isa("Unqualche::Modulo::Eccezione")) {
# gestisce Unqualche::Modulo::Eccezione
}
else {
# gestisce tutte le altre possibili eccezioni
}
}
Poiché perl converte in stringa i messaggi non gestiti prima di visualizzarli, potreste implementare un overload dell'operatore di conversione a stringa su tali oggetti eccezione. Consultate overload per maggiori dettagli.
Potete fare in modo che venga chiamata una funzione appena prima che die faccia il suo dovere, impostando un riferimento in $SIG{__DIE__}. La funzione indicata sarà chiamata con il testo dell'errore e può, volendo, modificare il messaggio d'errore chiamando nuovamente die. Si veda "$SIG{expr}" in perlvar per dettagli sull'utilizzo di %SIG, e "eval BLOCK" per qualche esempio. Nonostante questa funzionalità dovesse essere eseguita solo immediatamente prima dell'uscita dal programma, ma non è più così -- la funzione in $SIG{__DIE__} viene chiamata anche all'interno di blocchi o stringhe in eval()! Se si vuole che la funzione non faccia nulla in questi casi, mettere un
die @_ if $^S;
come prima linea della funzione (si veda "$^S" in perlvar). Poiché questo può causare effetti collaterali non desiderati, questo comportamento non intuitivo potrebbe essere modificato in una versione successiva.
Non è proprio una funzione. Restituisce il valore dell'ultimo comando nella sequenza dei comandi indicati da BLOCCO. Quando viene modificato da un modificatore di ciclo while o until, esegue il BLOCCO una volta prima di testare la condizione del ciclo (Su altre istruzioni, i modificatori di loop testano prima il condizionale).
do BLOCCO non conta come un ciclo, dunque le istruzioni di controllo del ciclo next, last o redo non possono essere usati per lasciare o ricominciare il blocco. Consultate perlsyn per strategie alternative.
Questa forma di chiamata a subroutine è deprecata. Consultate perlsub.
Utilizza il valore di ESPR come un nome di file ed esegue il contenuto del file come fosse uno script Perl.
do 'stat.pl';
è proprio come
eval `cat stat.pl`;
eccetto che è più efficiente e concisa, tiene traccia del nome file corrente per i messaggi d'errore, ricerca directory di @INC e aggiorna %INC se il file viene trovato. Consultate "Predefined Names" in perlvar [Nomi predefiniti, NdT] per queste varabili. Differisce anche per il fatto che il codice valutato con do NOMEFILE non può vedere i lessicali nello scope che lo include; eval STRINGA li vede. È lo stesso, comunque, nel fatto che esso riesegue un'analisi sintattica del file ogni qualvolta viene chiamato, dunque probabilmente non volete fare questo all'interno di un ciclo.
Se do non può leggere il file, esso restituisce undef e imposta $! con l'errore. Se do può leggere il file ma non lo può compilare, restituisce undef e imposta un messaggio di errore in $@. Se il file è compilato con successo, do restituisce il valore dell'ultima espressione valutata.
Va notato che l'inclusione di moduli di libreria viene fatta meglio con gli operatori use e require che eseguono anche un controllo automatico degli errori e sollevano un'eccezione se ci fosse un problema.
Potreste gradire l'utilizzo di do per leggere in un file di configurazione di un programma. Il controllo manuale degli errori può essere fatto in questo modo:
# legge nei file di configurazione: prima in quelli di sistema poi in quelli utente
for $file ("/share/prog/default.rc",
"$ENV{HOME}/.unqualcheprogrammarc")
{
unless ($valore_restituito = do $file) {
warn "non si e` potuto fare l'analisi sintattica di $file: $@" if $@;
warn "non si e` potuto eseguire do sul $file: $!" unless defined $valore_restituito;
warn "non si e` potuto eseguire il $file" unless $valore_restituito;
}
}
Questa funzione causa un immediato core dump. Si veda anche l'opzione da linea di comando -u in perlrun, che fa la stessa cosa. Principalmente è fatta in modo che possiate usare il programma undump (non fornito) per trasformare il vostro core dump in un eseguibile binario, dopo aver inizializzato tutte le vostre variabili all'inizio del programma. Quando il nuovo binario viene eseguito, inizierà con l'eseguire un goto ETICHETTA (con tutte le restrizioni di cui soffre goto). Pensate ad esso come ad un goto con un core dump nel mezzo, e poi una reincarnazione. Se ETICHETTA viene omesso, ricomincia il programma da capo.
ATTENZIONE: Ogni file aperto al momento del dump non sarà più aperto quando il programma si reincarnerà, con una possibile confusione di risultati dal lato del Perl.
Questa funzione è ora ampiamente obsoleta, in parte a causa dell'estrema difficoltà nel convertire un file di core in un eseguibile e perché è stato superato dai veri compilatori di backend che generano bytecode portabile e codice C compilabile. Questo è il motivo per cui ora lo dovreste invocare come CORE::dump(), se non volete essere avvisati di un possibile errore di battitura.
Se state considerando l'utilizzo di dump per rendere i vostri programmi più veloci, prendete in considerazione la generazione di bytecode o di codice C nativo come descritto in perlcc. Se state solamente tentando di accelerare uno script CGI, prendete in considerazione l'utilizzo di mod_perl, estensione di Apache, oppure il modulo CPAN CGI::Fast. Potreste prendere in considerazione anche l'autoloading o il selfloading, che almeno fanno sembrare più veloce il vostro programma.
Quando viene chiamato in un contesto di lista, restituisce una lista di due elementi che costituiscono la chiave e il valore del prossimo elemento di un hash, in maniera tale che possiate iterare su di esso. Quando viene chiamato in un contesto scalare, restituisce soltanto la chiave del prossimo elemento dell'hash.
Gli elementi vengono restituiti in un ordine apparentemente casuale. L'effettivo ordine casuale è soggetto a cambiamenti nelle future versioni di Perl, ma è garantito essere lo stesso ordine che la funzione keys o values produrrebbero dallo stesso hash (non modificato). A partire dalla versione 5.8.1 di Perl, per questioni di sicurezza l'ordinamento è differente anche tra differenti esecuzioni di Perl (si consulti "Algorithmic Complexity Attacks" in perlsec ["Attacchi di Complessità Algoritmica", NdT]).
Quando l'hash è stato letto interamente, in contesto di lista viene restituito un array null (che quando viene assegnato produce un valore falso 0), e undef in contesto scalare. La prossima chiamata a each dopo questa comincerà l'iterazione un'altra volta. Esiste un singolo iteratore per ogni hash, condiviso da tutte le chiamate a each, keys e values nel programma; può essere azzerato leggendo tutti gli elementi dall'hash, oppure valutando keys HASH o values HASH. Se aggiungete o cancellate elementi a un hash mentre state iterando su di esso, potreste avere degli elementi saltati o ripetuti, quindi non fatelo. Eccezione: è sempre sicuro cancellare l'elemento restituito più di recente da each(), il che significa che il seguente codice funzionerà:
while (($key, $value) = each %hash) {
print $key, "\n";
delete $hash{$key}; # E<egrave> sicuro
}
Il seguente codice stampa l'ambiente come il programma printenv(1), con l'unica differenza che lo fa in un ordine differente:
while (($key,$value) = each %ENV) {
print "$key=$value\n";
}
Consultate anche keys, values e sort.
Restituisce 1 se la successiva lettura su FILEHANDLE restituirà la fine del file oppure se FILEHANLDE non è aperto. FILEHANDLE può essere un'espressione il cui valore restituisce il filehandle effettivo. (Va notato che questa funzione legge realmente un carattere e poi esegue una ungetc su di esso, dunque ciò non è molto utile in un contesto interattivo). Non leggete da un file di terminale (oppure non chiamate eof(FILEHANDLE) su di esso) dopo che si è raggiunta la fine-del-file. Se lo fate, i tipi di file quali i terminali potrebbero perdere la condizione di fine-del-file.
Un eof senza un argomento utilizza l'ultimo file letto. L'uso di eof() con parentesi vuote, è molto differente. Si riferisce allo pseudo file formato dai file elencati sulla linea di comando e acceduti attraverso l'operatore <>. Poiché <> non è esplicitamente aperto come lo è un normale filehandle, un eof() prima che venga usato un <> farà sì che venga esaminato @ARGV per determinare se sia disponibile l'input. In maniera analoga, un eof() dopo che <> abbia restituito fine-del-file, presupporrà che stiate elaborando un'altra lista di @ARGV, e se non avete impostato @ARGV, esso leggerà l'input da STDIN; consultate "I/O Operators" in perlop ["Operatori di I/O", NdT].
In un ciclo while (<>), eof o eof(ARGV) possono essere usati per determinare la fine di ogni file, eof() determinerà solo la file dell'ultimo file. Esempi:
# ripristina la numerazione di linea su ogni file di input
while (<>) {
next if /^\s*#/; # tralascia i commenti
print "$.\t$_";
} continue {
close ARGV if eof; # Non eof()!
}
# inserisce delle lineette appena prima dell'ultima linea dell'ultimo file
while (<>) {
if (eof()) { # controlla la fine dell'ultimo file
print "--------------\n";
}
print;
last if eof(); # necessario se stiamo leggendo da terminale
}
Suggerimento pratico: in Perl non si ha quasi mai la necessità di usare eof visto che gli operatori di input restituiscono tipicamente undef quando esauriscono i dati o se c'è stato un errore.
Nella prima forma, il valore restituito da ESPR viene analizzato sintatticamente ed eseguito come se fosse un piccolo programma Perl. Il valore dell'espressione (che viene di per sé determinato all'interno del contesto scalare) viene prima controllato dal punto di vista sintattico e, se non ci sono stati errori, eseguito nel contesto lessicale del programma Perl corrente, in maniera che tutte le definizioni di formato, le subroutine, e i valori dati alle variabili rimangano intatti. Va notato che il valore viene verificato sintatticamente ogni qualvolta l'eval effettua un'esecuzione. Se ESPR viene omessa, esso valuta $_. Questa forma viene usata tipicamente per ritardare la verifica sintattica e la successiva esecuzione del testo di ESPR fino al tempo di esecuzione.
Nella seconda forma, il codice all'interno del BLOCCO viene verificato sintatticamente solo una volta, allo stesso momento in cui il codice che circonda lo stesso eval viene verificato sintatticamente, ed eseguito all'interno del contesto del programma Perl corrente. Questa forma viene usata tipicamente per catturare le eccezioni in maniera più efficiente che non la prima (vedete qui sotto), pur fornendo anche il vantaggio di controllare il codice dentro BLOCCO a tempo di compilazione.
Il punto e virgola finale, se presente, potrebbe essere omesso dal valore di ESPR o all'interno del BLOCCO.
In entrambe le forme, il valore restituito è il valore dell'ultima espressione valutata all'interno del mini-programma; può anche essere usata un'istruzione return, proprio come per le subroutine. L'espressione che fornisce il valore restituito, viene valutata in un contesto vuoto, scalare oppure di lista, a seconda del contesto dell'eval stesso. Si veda "wantarray" per maggiori informazioni su come può essere valutata la valutazione del contesto.
Se ci fosse un errore di sintassi o un errore a tempo di esecuzione oppure se venisse eseguita un'istruzione die, eval restituisce un valore indefinito e in $@ viene posto il messaggio d'errore. Se non ci fossero errori, $@ viene garantito essere una stringa nulla. Fate attenzione al fatto che utilizzare eval non impedisce al perl di stampare gli avvertimenti su STDERR, né tantomeno il testo degli avvertimenti viene memorizzato in $@. Per fare entrambe le cose, dovete usare l'agevolazione data da $SIG{__WARN__} oppure disabilitare gli avvertimenti all'interno del BLOCCO o ESPR utilizzando no warnings 'all'. Consultate "warn", perlvar, warnings e perllexwarn.
Va notato che, dato che eval cattura gli errori altrimenti bloccanti, è utile per determinare se una particolare caratteristica (quale socket o symlink) è implementata. È anche il meccanismo di cattura delle eccezioni, dove l'operatore die viene usato per sollevare le eccezioni.
Se il codice che deve essere eseguito non varia, potete usare la forma eval-BLOCCO per catturare gli errori a tempo di esecuzione senza incorrere nella penalizzazione di ricompilare ogni volta. L'errore, se c'è, viene ancora restituito in $@. Esempi:
# rende la divisione per zero non bloccante
eval { $risposta = $a / $b; }; warn $@ if $@;
# stessa cosa, ma meno efficiente
eval '$risposta = $a / $b'; warn $@ if $@;
# un errore a tempo di compilazione
eval { $risposta = }; # ERRATO
# un errore a tempo di esecuzione
eval '$risposta ='; # imposta $@
Usare la forma eval{} per catturare le eccezioni nelle librerie, presenta qualche complicazione. A causa del corrente, opinabilmente non corretto, stato degli hook di __DIE__, potreste non voler innescare alcun hook per quei __DIE__ che il codice utente potrebbe aver installato. Per questo scopo si può utilizzare il costrutto local $SIG{__DIE__}, come mostrato in questo esempio:
# una trappola molto privata per l'eccezione divisione-per-zero
eval { local $SIG{'__DIE__'}; $risposta = $a / $b; };
warn $@ if $@;
Questo ha un significato speciale, dato che gli hook di __DIE__ possono chiamare die un'altra volta, e ciò ha l'effetto di cambiare i loro messaggi d'errore:
# gli hook di __DIE__ possono modificare i messaggi d'errore
{
local $SIG{'__DIE__'} =
sub { (my $x = $_[0]) =~ s/pippo/pluto/g; die $x };
eval { die "pippo qua e` vivo" };
print $@ if $@; # stampa "pluto qua e` vivo"
}
Visto che questo favorisce le azioni a distanza, questo comportamento non intuitivo sarà probabilmente risolto in una versione ventura.
Con un eval, dovreste prestare particolare attenzione nel ricordare cosa si sta esaminando quando:
eval $x; # CASO 1
eval "$x"; # CASO 2
eval '$x'; # CASO 3
eval { $x }; # CASO 4
eval "\$$x++"; # CASO 5
$$x++; # CASO 6
I casi 1 e 2 qua sopra, hanno un comportamento identico: essi eseguono il codice contenuto nella variabile $x. (Sebbene il caso 2 ha delle virgolette che sono ingannevoli che fanno sì che il lettore si chieda cos'altro stia accadendo (nulla)). I casi 3 e 4, similmente, si comportano allo stesso modo: eseguono il codice in '$x', che non fa altro che restituire il valore di $x. (Il caso 4 è preferibile solamente per ragioni visuali, ma ha anche il vantaggio di compilare a tempo di compilazione invece che a tempo di esecuzione). Il caso 5 è un luogo dove, di norma, vorreste usare le virgolette, eccetto che in questa particolare situazione, invece potete semplicemente usare i riferimenti simbolici, proprio come nel caso 6.
eval BLOCCO non viene considerata come un ciclo, dunque le istruzioni di controllo di un ciclo next, last o redo non possono essere usate per lasciare o reiniziare il blocco.
Va notato che come caso davvero speciale, un eval '' eseguito all'interno del package DB non vede l'usuale scope lessicale che lo circonda ma piuttosto lo scope del primo pezzo di codice che non appartiene al package DB che l'ha chiamato. Di norma, non si ha bisogno di preoccuparsi di questo a meno che non si stia scrivendo un debugger del Perl.
La funzione exec esegue un comando di sistema e non ritorna, usate system invece di exec se volete che ritorni. Essa fallisce e restituisce falso solo se il comando non esiste ed è eseguito direttamente invece che tramite la shell dei comandi di sistema (vedete qui sotto).
Poiché è un comune errore usare exec invece di system, il Perl avvisa se non c'è un'istruzione che segue che non sia die, warn o exit (se viene impostato -w, ma questo lo si fa sempre). Se davvero si vuol far seguire exec con qualche altra istruzione, per evitare l'avvertimento si può usare una di queste modalità:
exec ('pippo') or print STDERR "pippo non puo` essere eseguito: $!";
{ exec ('pippo') }; print STDERR "pippo non puo` essere eseguito: $!";
Se ci fosse più di un argomento nella LISTA o se la LISTA è un array con più di un valore, chiama execvp(3) con gli argomenti della LISTA. Se c'è solo un argomento scalare o un array con un solo argomento, l'argomento viene esaminato alla ricerca di metacaratteri di shell e, se presenti, l'intero argomento viene passato alla shell dei comandi del sistema per l'analisi sintattica (questa è /bin/sh -c su piattaforme Unix ma può variare su altre piattaforme). Se nell'argomento non ci sono metacaratteri di shell, esso viene diviso in parole e passato direttamente a execvp che è più efficiente. Esempi:
exec '/bin/echo', 'I vostri argomenti sono: ', @ARGV;
exec "sort $file_in_output | uniq";
Se davvero non volete eseguire il primo argomento ma volete mentire al programma che si sta eseguendo riguardo al proprio nome, potete specificare il programma che si vuole realmente eseguire come un "oggetto indiretto" (senza alcuna virgola) davanti alla LISTA (Questo forza sempre l'interpretazione della LISTA come una lista multivalore anche se c'è solo un singolo scalare nella lista). Ad esempio:
$shell = '/bin/csh';
exec $shell '-sh'; # fa finta che sia una shell di login
oppure, più direttamente,
exec {'/bin/csh'} '-sh'; # fa finta che sia una shell di login
Quando gli argomenti vengono eseguiti attraverso la shell di sistema, i risultati saranno soggetti ai sui cavilli e alle sue capacità. Consultate "`STRING`" in perlop per i dettagli.
Usare un oggetto indiretto con exec o system è anche più sicuro. Questo utilizzo (che funziona bene anche con system()) forza l'interpretazione degli argomenti come fossero una lista multivalore, anche se la lista avesse solo un argomento. In questo modo siete al sicuro dalle wildcard [caratteri jolly, NdT] di espansione della shell o dalla separazione delle parole che contengono degli spazi.
@arg = ( "echo sorpresa" );
exec @arg; # soggetto agli escape della shell
# if @args == 1
exec { $arg[0] } @arg; # sicuro anche con una lista di un argomento
La prima versione, quella senza l'oggetto indiretto, ha eseguito il programma echo passandogli un argomento "sorpresa". La seconda versione non l'ha passato, essa ha provato ad eseguire un programma chiamato letteralmente "echo sorpresa", non l'ha trovato e ha impostato $? ad un valore diverso da zero ad indicare il fallimento.
A partire dalla versione 5.6.0, il Perl cerca di terminare le operazioni di I/O in corso su tutti i file aperti per l'output prima di eseguire l'exec, ma questo potrebbe non essere supportato su alcune piattaforme (consultate perlport). Per essere sicuri, dovreste impostare $| ($AUTOFLUSH nel modulo English) oppure chiamare il metodo autoflush() di IO::Handle su ogni handle aperto, per evitare di perdere l'output.
Va notato che exec non chiamerà i vostri blocchi END né invocherà nessun metodo DESTROY nei vostri oggetti.
Data un'espressione che specifica un elemento di un hash o di un array, restituisce vero se l'elemento specificato nell'hash o nell'array è mai stato inizializzato, anche se il corrispondente valore è indefinito. L'elemento non viene autovivificato se non esiste.
print "Esiste\n" if exists $hash{$key};
print "Definito\n" if defined $hash{$key};
print "Vero\n" if $hash{$key};
print "Esiste\n" if exists $array[$index];
print "Definito\n" if defined $array[$index];
print "Vero\n" if $array[$index];
Un elemento di un hash o di un array può essere vero solo se è definito e definito solo se esiste, ma il viceversa non necessariamente mantiene il valore vero.
Data un'espressione che specifichi il nome di una subroutine, restituisce vero se la subroutine specificata è stata dichiarata, anche se è indefinita. Menzionare il nome di una subroutine per exists o defined non conta come il dichiararla. Va notato che una subroutine che non esiste può essere ancora richiamabile: il suo package potrebbe avere un metodo AUTOLOAD che lo fa nascere all'improvviso la prima volta che viene chiamato, consultate perlsub.
print "Esiste\n" if exists &subroutine;
print "Definito\n" if defined &subroutine;
Va notato che ESPR può essere arbitrariamente complicata finché l'operazione conclusiva è una ricerca della chiave di un hash o di un array o del nome di una subroutine:
if (exists $ref->{A}->{B}->{$chiave}) { }
if (exists $hash{A}{B}{$chiave}) { }
if (exists $ref->{A}->{B}->[$ix]) { }
if (exists $hash{A}{B}[$ix]) { }
if (exists &{$ref->{A}{B}{$chiave}}) { }
Sebbene l'array o l'hash più profondamente annidato non nascerà all'improvviso solo perché la sua esistenza è stata verificata, quelli intermedi lo faranno. Dunque $ref->{"A"} e $ref->{"A"}->{"B"} nasceranno all'improvviso a causa del test di esistenza per l'elemento $chiave visto sopra. Questo avviene ovunque sia usato l'operatore freccia, incluso anche:
undef $ref;
if (exists $ref->{"Una qualche chiave"}) { }
print $ref; # stampa HASH(0x80d3d5c)
Questa sorprendente autovivificazione in quello che non appare essere, ad una prima o anche seconda occhiata, un lvalue [valore a sinistra di un'espressione, NdT], potrebbe essere corretto in una versione futura.
Consultate "Pseudo-hashes: Using an array as a hash" in perlref ["Pseudo-hash: Usare un array come un hash", NdT] per le specifiche su come exists() si comporta quando usato su uno pseudo-hash.
L'uso di una chiamata a subroutine, invece che un nome di subroutine, come argomento di exists() è un errore.
exists ⊂ # OK
exists &sub(); # Errore
Valuta ESPR ed esce immediatamente con quel valore. Esempio:
$risp = <STDIN>;
exit 0 if $risp =~ /^[Xx]/;
Date un'occhiata anche a die. Se ESPR viene omessa, esce con lo stato 0. I soli valori universalmente riconosciuti per ESPR sono 0 per il successo e 1 per l'errore; altri valori sono soggetti ad interpretazione in relazione all'ambiente nel quale il programma Perl è in esecuzione. Per esempio, uscire con un 69 (EX_UNAVAILABLE) da un filtro di sendmail per le mail in arrivo, provocherà, da parte del programma che spedisce le mail, la restituzione dell'oggetto che non è stato recapitato, ma questo non è vero dappertutto.
Non usate exit per interrompere una subroutine se c'è una qualsiasi possibilità che qualcuno possa volere intercettare quale che sia l'errore capitato. Usate die invece, che può essere intercettato da un eval.
La funzione exit() non esce sempre immediatamente. Essa chiama per prima una qualunque delle routine END definite, ma queste routine END non possono esse stesse interrompere l'uscita. Inoltre tutti i distruttori dell'oggetto che devono essere chiamati, sono chiamati prima dell'uscita vera e propria. Se questo fosse un problema, potete chiamare POSIX:_exit($stato) per evitare END e il processo di distruzione. Consultate perlmod per i dettagli.
Restituisce e (la base naturale del logaritmo) elevato alla potenza di ESPR. Se ESPR viene omessa, restituisce exp($_).
Implementa la funzione fcntl(2). Probabilmente prima dovrete dichiarare
use Fcntl;
per ottenere le giuste definizioni delle costanti.
Il trattamento degli argomenti e la restituzione di valore funziona come nella ioctl più sotto. Per esempio:
use Fcntl;
fcntl($filehandle, F_GETFL, $packed_return_buffer)
or die "impossibile eseguire fcntl F_GETFL: $!";
Non dovete controllare il valore restituito da fnctl con defined. Come ioctl, esso mappa uno 0 restituito dalla chiamata di sistema in uno "0 ma vero" in Perl. Questa stringa è vera in un contesto booleano e 0 in un contesto numerico. Essa viene anche esonerata dal normale warning -w su una impropria conversione numerica.
Va notato che fcntl produrrà un errore bloccante se usata su un elaboratore che non implementa fcntl(2). Consultate il modulo Fcntl o la manpage di fcntl(2) per sapere quali funzioni sono disponibili sul vostro sistema.
Ecco un esempio dell'impostazione di un filehandle chiamato REMOTE ad essere non bloccante a livello di sistema. Dovete tuttavia negoziare $| voi stessi.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
$flag = fcntl(REMOTE, F_GETFL, 0)
or die "Impossibile ottenere i flag per il socket: $!\n";
$flag = fcntl(REMOTE, F_SETFL, $flags | O_NONBLOCK)
or die "Impossibile impostare i flag per il socket: $!\n";
Restituisce il descrittore di file per un filehandle, o il valore indefinito se il filehandle non è aperto. Lo scopo di questa funzione è principalmente quello di preparare le mappe di bit per select e per operazioni POSIX di basso livello sulla gestione dei tty. Se FILEHANDLE è un'espressione, il valore viene considerato come filehandle indiretto, generalmente il suo nome.
Potete usare questa funzione per verificare che due filehandle si riferiscano allo stesso descrittore:
if(fileno(QUESTO) == fileno(QUELLO)) {
print "QUESTO e QUELLO sono duplicati\n";
}
(I filehandle collegati ad oggetti in memoria con le nuove funzionalità di open potrebbero restituire il valore indefinito nonostante siano aperti).
Chiama flock(2), o una sua emulazione, su FILEHANDLE. Restituisce vero in caso di successo, falso in caso di fallimento. Produce un errore bloccante se usato su un calcolatore che non implementa flock(2), il lock di fcntl(2) oppure lockf(3). flock è l'interfaccia portabile del Perl al lock dei file, sebbene esegua dei lock solo su interi file e non su record.
Due semantiche di flock potenzialmente non ovvie ma tradizionali sono che esso aspetta indefinitamente fino a che il lock non sia assegnato e che i suoi lock sono solamente consultivi. Tali lock discrezionali sono molto flessibili ma offrono minori garanzie. Questo significa che i programmi che non usano anch'essi flock possono modificare quei file sottoposti a lock con flock. Per i dettagli consultate perlport, la vostra specifica documentazione sul port oppure le vostre manpage, specifiche del sistema. Se state scrivendo programmi portabili, è meglio che assumiate un comportamento tradizionale. (Ma se non lo state facendo, dovreste sempre sentirvi perfettamente liberi di scrivere per le vostre idiosincrasie del sistema (chiamate talvolta "caratteristiche"). Pedisseque aderenze agli interessi della portabilità non dovrebbero intralciare nel portare il lavoro a termine).
OPERAZIONE è una di queste: LOCK_SH, LOCK_EX o LOCK_UN, combinate eventualmente con LOCK_NB. Queste costanti sono tradizionalmente i valori 1, 2, 8 e 4, ma potete usare i nomi simbolici se li importate dal modulo Fcntl, sia individualmente sia come gruppo, usando il tag ':flock'. LOCK_SH richiede un lock condiviso, LOCK_EX richiede un lock esclusivo e LOCK_UN rilascia un lock richiesto precedentemente. Se su LOCK_NB viene effettuato un or a livello di bit con LOCK_SH o LOCK_EX, allora flock terminerà immediatamente piuttosto che bloccare aspettando il lock (controllate lo stato di ritorno per vedere se lo avete ottenuto).
Per evitare la possibilità di una non coordinazione, ora il Perl svuota FILEHANDLE prima di effettuare un lock o un unlock su di esso.
Va notato che l'emulazione insita in lockf(3) non fornisce lock condivisi e richiede che FILEHANDLE sia aperto per scopi di scrittura. Queste sono le semantiche che lockf(3) implementa. Tuttavia, molti se non tutti i sistemi implementano lockf(3) in termini del lock di fcntl(2), dunque le differenti semantiche non dovrebbero infastidire troppe persone.
Va notato che l'emulazione fcntl(2) di flock83) richiede che FILEHANLDE sia aperto per scopi di lettura per usare LOCK_SH e richiede che sia aperto per scopi di scrittura per usare LOCK_EX.
Va notato anche che alcune versioni di flock non possono effettuare lock su oggetti in rete; per questo caso sarebbe necessario usiaste fcntl che è più specificatamente orientata al sistema. Se preferite, potete forzare il Perl ad ignorare la vostra funzione flock(2) di sistema, e dunque fornire la vostra emulazione basata su fcntl(2), passando l'opzione -Ud_flock al programma Configure quando si configura perl.
Ecco un un programma che aggiunge mail al file mailbox per sistemi BSD.
use Fcntl ':flock'; # importa le costanti LOCK_*
sub lock {
flock(MBOX,LOCK_EX);
# e, nel caso che qualcuno abbia aggiunto
# mentre si era in attesa...
seek(MBOX, 0, 2);
}
sub unlock {
flock(MBOX,LOCK_UN);
}
open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}")
or die "Impossibile aprire mailbox: $!";
lock();
print MBOX $mess,"\n\n";
unlock();
Su sistemi che supportano un vero flock(), i lock sono ereditati attraverso le chiamate fork(), mentre quelli che devono ricorrere alla pià capricciosa funzione fcntl(), perdono i lock, rendendo pià difficoltoso lo scrivere server.
Consultate anche DB_File per altri esempi su flock().
Effettua una chiamata di sistema a fork(2), al fine di creare un nuovo processo che esegua lo stesso programma a partire dal punto della chiamata. Restituisce il pid del figlio al processo genitore, 0 al processo figlio, oppure undef se la chiamata non ha successo. I descrittori dei file (ed a volte anche i lock su tali descrittori) vengono condivisi, mentre tutto il resto viene copiato. Sulla maggior parte dei sistemi che supportano fork(), l'efficienza è stata molto curata (per esempio, usando la tecnologia copy-on-write [copia-su-scrittura, NdT] sulle pagine dati), facendo di essa il paradigma dominante per il multitasking negli ultimi decenni.
A partire dalla versione 5.6.0, Perl cercherà di completare le operazioni di scrittura su tutti i file aperti in output prima di effettuare il fork del processo figlio, ma ciò potrebbe non essere supportato su alcuni sistemi (consultate perlport). Per essere sicuri, potreste dover impostare $| ($AUTOFLUSH con il modulo English) o chiamare il metodo autoflush() di IO::Handle sugli eventuali handle aperti, così da evitare un output duplicato.
Se utilizzate fork senza mai attendere i vostri figli, accumulerete zombie. Su alcuni sistemi, potete evitare ciò impostando $SIG{CHLD} a "IGNORE". Consultate anche perlipc per ulteriori esempi su fork e su come liberarsi dei figli moribondi.
Va notato che se il figlio che avrete creato con fork eredita dei descrittori di file di sistema come STDIN e STDOUT che sono in realtà connessi da una pipe o un socket, anche se uscite, il server remoto (come, ad esempio, uno script CGI o un processo in background lanciato da una shell remota) non si accorgeranno che voi avete finito. Se ciò rappresenta un problema, dovrete riaprire tali descrittori verso /dev/null.
Dichiara un formato di descrizione che verrà usato dalla funzione write. Per esempio:
format Qualcosa =
Test: @<<<<<<<< @||||| @>>>>>
$str, $%, '$' . int($num)
.
$str = "arnese";
$num = $costo/$quantita;
$~ = 'Qualcosa';
write;
Consultate perlform per molti dettagli ed esempi.
Questa è una funzione interna usata dai format, tuttavia potete anche richiamarla. Essa formatta (consultate perlform) una lista di valori in conformità con i contenuti di DESCRIZIONE, ponendo l'output nell'accumulatore del formato di output, $^A (o $ACCUMULATOR con il modulo English). Infine, quando viene eseguito un write, i contenuti di $^A vengono scritti su qualche filehandle. Potreste anche leggere $^A da sé e poi reimpostare $^A a "". Va notato che un format tipicamente esegue un formline per linea di formato ma la funzione formline di per sé non tiene conto di quanti a capo sono inseriti nella DESCRIZIONE. Questo significa che i token ~ e ~~ tratteranno l'intera DESCRIZIONE come una singola linea. Perciò potreste avere la necessità di usare formline multipli per implementare un singolo record di formato, proprio come il compilatore di formato.
Prestate attenzione se mettete tra virgolette doppie alla descrizione, visto che un carattere @ può assumere il significato di inizio del un nome di array. formline restituisce sempre vero. Consultate perlform per altri esempi.
Restituisce il prossimo carattere dal file di input associato con il FILEHANDLE, oppure il valore indefinito alla fine del file o se c'è stato un errore (in quest'ultimo caso viene impostato $!). Se FILEHANDLE viene omesso, legge da STDIN. Questo non è particolarmente efficiente. Comunque, non può essere usata da se stessa per prelevare dei singoli caratteri senza aspettare che l'utente abbia premuto invio. Per questo, provate piuttosto qualcosa come:
if ($STILE_BSD) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", '-icanon', 'eol', "\001";
}
$tasto = getc(STDIN);
if ($STILE_BSD) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", 'icanon', 'eol', '^@'; # null ASCII
}
print "\n";
Determinare come deve essere impostato $STILE_BSD viene lasciato come esercizio al lettore.
La funzione POSIX::getattr può fare questo in maniera più portabile su sistemi che vogliono farsi passare per essere conformi a POSIX. Date un'occhiata anche al modulo Term::ReadKey, dal più vicino sito CPAN; dettagli su CPAN possono essere trovati su "CPAN" in perlmodlib.
Implementa la funzione della libreria C che ha lo stesso nome, la quale su molti sistemi restituisce il login corrente da /etc/utmp, se presente. Se non presente, usate getpwuid.
$login = getlogin || getpwuid($<) || "Kilroy";
Non prendete in considerazione getlogin per l'autenticazione: non è sicura quanto getpwuid.
Restituisce l'indirizzo compattato (sockaddr) dell'altro capo della connessione SOCKET.
use Socket;
$suosockaddr = getpeername(SOCK);
($porta, $indirizzo) = sockaddr_in($suosockaddr);
$suohostname = gethostbyaddr($indirizzo, AF_INET);
$suoindirizzo = inet_ntoa($indirizzo);
Restituisce il gruppo del processo corrente per il PID specificato. Usate un PID di 0 per ottenere il gruppo del processo corrente per il processo corrente. Solleverà un'eccezione se usato su elaboratori che non implementano getpgrp(2). Se PID viene omesso, restituisce il gruppo del processo del processo corrente. Va notato che la versione POSIX di getpgrp non accetta un PID come argomento, dunque solo PID==0 è davvero portabile.
Restituisce l'id del processo genitore.
Nota per gli utenti Linux: le funzioni C getpid() e getppid() implementate in Linux, restituiscono valori differenti se chiamate da thread diversi. Per mantenere la portabilità, questo comportamento non si riflette nella funzione Perl getppid(), che restituisce lo stesso valore anche se chiamata da thread diversi. Per richiamare la funzione getppid() di sistema si può utilizzare il modulo CPAN Linux::Pid.
Restituisce la priorità corrente per un processo, un gruppo di processi, o un utente. (Consultate getpriority(2)). Solleverà un'eccezione bloccante se usata in una macchina che non implementa getpriority(2).
Queste routine compiono le stesse funzioni delle loro controparti nella libreria di sistema. In un contesto di lista, restituiscono i valori dalle varie routine di get [ottenere, NdT], come segue:
($nome,$passwd,$uid,$gid,
$quota,$commento,$gcos,$dir,$shell,$scadenza) = getpw*
($nome,$passwd,$gid,$members) = getgr*
($nome,$alias,$tipoind,$lungh,@indirizzi) = gethost*
($nome,$alias,$tipoind,$net) = getnet*
($nome,$alias,$proto) = getproto*
($nome,$alias,$porta,$proto) = getserv*
(Se la voce non esiste, otterrete una lista nulla).
L'esatto significato del campo $gcos varia ma di solito esso contiene il vero nome dell'utente (rispetto al nome del login) e altre informazioni pertinente all'utente. Fate attenzione, comunque, che su molti sistemi gli utenti sono in grado di cambiare queste informazioni e dunque ciò non può essere verificato e dunque $gcos è un dato potenzialmente dannoso (taint) (consultate perlsec). $passwd e $shell, la password cifrata dell'utente e la shell di login sono anch'esse dei dati potenzialmente dannosi per il medesimo motivo.
In contesto scalare, otterrete il nome a meno che la funzione non sia ottenuta con una ricerca per nome, nel qual caso otterrete l'altra cosa, qualunque essa sia (se l'elemento non esiste, otterrete il valore indefinito). Per esempio:
$uid = getpwnam($nome);
$nome = getpwuid($num);
$nome = getpwent();
$gid = getgrnam($nome);
$nome = getgrgid($num;
$nome = getgrent();
#ecc.
In getpw*(), i campi $quota, $commento e $scadenza sono casi speciali nel senso che in molti sistemi non sono supportati. Se $quota non è supportato, è uno scalare vuoto. Se è supportato, di solito codifica il valore della quota del disco. Se $commento non è supportato, è uno scalare vuoto. Se è supportato di solito codifica dei commenti amministrativi sull'utente. In alcuni sistemi il campo $quota può essere $cambiamento oppure $eta, campi che hanno a che fare con l'obsolescenza delle password. In alcuni sistemi, il campo $commento può essere $classe. Il campo $scadenza, se presente, codifica il periodo di scadenza dell'account o della password. Per la disponibilità e l'esatto significato di questi campi nel vostro sistema, consultate la documentazione di getpwnam(3) e il file pwd.h. Potete anche scoprire dall'interno del Perl che significato hanno i vostri $quota e $commento e se possedete il campo $expire, tramite l'utilizzo del modulo Config e i valori d_pwquota, d_pwage, d_pwchange, d_pwcomment e d_pwexpire. I file con le password shadow sono supportati solo se l'azienda produttrice di software che vi fornisce li ha implementati in quel modo intuitivo che, chiamando le routine della libreria C usuale, ottiene le versioni shadow se siete in esecuzione con i privilegi o se esistono le funzioni shadow(3) come si trovano in System V (questo include Solaris e Linux). Quei sistemi che implementano un'infrastruttura proprietaria per le password shadow è improbabile che siano supportati.
Il valore di $members restituito da getgr*() è una lista separata da spazi dei nomi di login dei membri del gruppo.
Per le funzioni gethost*(), se la variabile h_errno è supportata in C, vi sarà restituita attraverso $? se la chiamata di funzione fallisce. Il valore @addrs restituito da una chiamata che ha avuto successo è una lista di indirizzi grezza, restituita dalla corrispondente chiamata della libreria di sistema. In ambito Internet, ogni indirizzo è lungo 4 byte e potete effettuare unpack su esso scrivendo qualcosa come:
($a,$b,$c,$d) = unpack('C4',$ind[0]);
La libreria Socket rende questo un po' più facile:
use Socket;
$indint = inet_aton("127.1"); # o qualsiasi indirizzo
$nome = gethostbyaddr($indint, AF_INET);
# oppure andando nell'altro verso
$strind = inet_ntoa($indint);
Se siete stanchi di tenere a mente quali valori corrispondono a quali elementi della lista restituita, vengono fornite delle interfacce per nome nei moduli standard: File::stat, Net::hostent, Net::netent, Net::protoent, Net::servent, Time::gmtime, Time::localtime e User::grent. Queste si sovrappongono alle normali funzioni interne, fornendo versioni che restituiscono oggetti con i nomi appropriati per ogni campo. Per esempio:
use File::stat; use User::pwent; $suo = (stat($nomefile)->uid == pwent($chiunque)->uid);
Anche se sembra che siano gli stessi metodi di chiamata (uid), non lo sono perché un oggetto File::stat è diverso da un oggetto User::pwent.
Restituisce l'indirizzo compattato sockaddr di questa estremità della connessione SOCKET nel caso non si conosca l'indirizzo, visto che si hanno diversi differenti IP a cui la connessione potrebbe partecipare.
use Socket;
$miosockaddr = getsockname(SOCK);
($porta, $mioind) = sockaddr_in($miosockaddr);
printf "Connesso a %s [%s]\n",
scalar gethostbyaddr($mioind, AF_INET),
inet_ntoa($mioind);
Consulta l'opzione di nome NOMEOPZ associata al SOCKET ad un dato LIVELLO. Le opzioni possono esistere su livelli di protocollo multipli a seconda del tipo di socket, ma esisterà almeno il livello di socket più elevato SOL_SOCKET (definito nel modulo Socket). Per consultare le opzioni ad un altro livello, dovrebbe venir fornito il numero di protocollo dell'appropriato protocollo che controlla l'opzione. Per esempio, per indicare che un'opzione sarà interpretata dal protocollo TCP, LIVELLO dovrà essere impostato come numero di protocollo di TCP, che potete ottenere usando getprotobyname.
La chiamata restituisce una stringa compattata che rappresenta l'opzione del socket richiesta, oppure undef se c'è un errore (il motivo dell'errore sarà in $!). Quello che c'è esattamente nella stringa compattata dipende da LIVELLO e NOMEOPZ, consultate la vostra documentazione di sistema per i dettagli. Comunque, un caso molto comune è che l'opzione sia un intero, nel qual caso il risultato sarà un intero compattato che potete decodificare usando unpack con il formato i (o I).
Un esempio che testa se l'algoritmo di Nagle sia attivato su di un socket:
use Socket qw(:all);
defined(my $tcp = getprotobyname("tcp"))
or die "Non posso determinare il numero di protocollo per tcp";
# my $tcp = IPPROTO_TCP; # Alternativo
my $compattato = getsockopt($socket, $tcp, TCP_NODELAY)
or die "Non posso interrogare l'opzione TCP_NODELAY del socket: $!";
my $senzaritardo = unpack("I", $compattato);
print "L'algoritmo di Nagle e`", $senzaritardo ? "non attivato\n" : "attivato\n";
In contesto di lista, restituisce una lista (anche vuota) derivante dall'espansione del nome del file passato come ESPR, come farebbe la shell standard di Unix /bin/csh. In contesto scalare, glob itera attraverso i risultati di tale espansione, restituendo undef quando la lista è esaurita. Questa è la funzione interna che implementa l'operatore <*.c>, ma potete usarla direttamente. Se ESPR viene omessa, glob() utilizza $_. L'operatore <*.c> è discusso in maggiore dettaglio in "I/O Operators" in perlop ["Operatori di I/O", NdT].
A partire dalla versione 5.6.0, questo operatore è implementato utilizzando l'estensione standard File::Glob. Consultate File::Glob per i dettagli.
Converte l'ora restituita dalla funzione time in una lista di 9 elementi, con l'ora localizzata al fuso orario locale. è tipicamente usato come segue:
# 0 1 2 3 4 5 6 7 8
($sec,$min,$ore,$giom,$mese,$anno,$gios,$gioa,$oraleg) =
gmtime(time);
Tutti gli elementi della lista sono numerici, e derivano direttamente dalla 'struct tm' del C. $sec, $min e $ore sono i secondi, i minuti e le ore dell'orario specificato. $giom è il giorno del mese, e $mese è il mese stesso, nell'intervallo 0..11, in cui 0 indica Gennaio e 11 Dicembre. $anno è il numero di anni a partire dal 1900. Ciò significa che $anno è 123 nel 2023. $gios è il giorno della settimana, con 0 che indica Domenica e 3 Mercoledì. $gioa è il giorno dell'anno, nell'intervallo 0..364 (o <0..365> negli anni bisestili). $isdst è sempre 0.
Va notato che l'elemento $anno non contiene semplicemente le ultime due cifre dell'anno. Se assumete ciò, allora vi ritrovate a creare programmi non compatibili con l'anno 2000 (Y2K), e questo non volete farlo, vero?
Il modo corretto per ottenere un anno a 4 cifre è semplicemente:
$anno += 1900;
E per ottenere le ultime due cifre dell'anno (ad esempio '01' nel 2001) potete scrivere:
$anno = sprintf("%02d", $anno % 100);
Se ESPR viene omessa, gmtime() usa l'ora correte (gmtime(time)).
In contesto scalare, gmtime() restituisce il valore di ctime(3):
$stringa_diadesso = gmtime; # es. "Thu Oct 13 04:54:34 1994"
Se vi serve il tempo locale invece del GMT, usate la funzione "localtime" che è integrata in Perl. Consultate anche la funzione timegm fornita dal modulo Time::Local, e le funzioni strftime(3) e mktime(3) disponibili attraverso il modulo POSIX.
Questo valore scalare non dipende dal locale (consultate perllocale), ma è interno a Perl. Per ottenere stringhe di data simili, ma dipendenti dal locale, consultate gli esempi in "localtime".
Si consulti "gmtime" in perlport per ciò che concerne la portabilità.
La forma goto-ETICHETTA trova l'istruzione etichettata con ETICHETTA e riprende l'esecuzione da essa. Questa forma non può essere utilizzata per entrare in alcun costrutto che richieda inizializzazione, come una subroutine oppure un loop foreach. Inoltre, non può essere utilizzata per entrare in un costrutto che è eliminato in fase di ottimizzazione o per uscire da un blocco o da un subroutine passata a sort. Può essere utilizzato per saltare praticamente in qualsiasi altro posto all'interno dello scope dinamico, anche fuori dalle subroutine, ma di solito è meglio utilizzare qualche altro costrutto, come last o die. L'autore di Perl non ha mai sentito la necessità di servirsi di questa forma di goto (in Perl, appunto, C è un'altra questione). (La differenza è che C non offre loop provvisti di nome in combinazione al controllo sui loop. Perl lo fa, e ciò sostituisce la maggior parte degli usi strutturati di goto negli altri linguaggi).
La forma goto-ESPR si attende un nome di etichetta, il cui scope viene poi risolto dinamicamente. Questo permette l'utilizzo dei goto calcolati di FORTRAN, ma non è consigliato se state ottimizzando al fine di creare codice manutenibile:
goto ("PIPPO", "PLUTO", "PAPERINO")[$i];
La forma goto-&NOME è piuttosto diversa dalle altre forme di goto. In realtà non è affatto un goto nel suo significato normale, e non ha le croci associate agli altri goto. Invece, esce dalla subroutine corrente (causando la perdita di eventuali modifiche eseguite da local()) e chiama immediatamente la subroutine indicata utilizzando il valore corrente di @_. Questa forma è utilizzata dalle subroutine AUTOLOAD che desiderano caricare un'altra subroutine e poi far credere che sia stata quest'ultima ad essere chiamata sin dall'inizio (tuttavia eventuali modifiche a @_ effettuate dalla subroutine corrente vengono propagate all'altra). Dopo il goto, nemmeno caller sarà in grado di dire che questa subroutine è stata chiamata per prima.
Non è necessario che NOME sia il nome di una subroutine; può essere una variabile scalare contenente un riferimento a codice, oppure un blocco che fornisce un riferimento a codice.
è simile nello spirito, ma non uguale, a grep(1) e ai suoi congiunti. In particolare, non è limitata all'uso di espressioni regolari.
Valuta il BLOCCO o l'ESPR per ogni elemento della LISTA (assegnando localmente a $_ ogni elemento) e restituisce una valore di lista costituito da quegli elementi per i quali la valutazione dell'espressione restituisce il valore vero. In un contesto scalare, restituisce il numero di volte che l'espressione ha restituito valore vero.
@pippo = grep(!/^#/, @pluto); # spazza via i commenti
o equivalentemente,
@pippo = grep {!/^#/} @pluto; # spazza via i commenti
Va notato che $_ è un alias del valore dell'elemento della lista, quindi può essere usato per modificare elementi della LISTA. Benché utile e supportato, può causare risultati bizzarri se gli elementi della LISTA non sono variabili. Allo stesso modo, grep restituisce alias agli elementi della lista originale, in modo molto simile a quello in cui il ciclo for costruisce alias per gli elementi della lista. Per questa ragione modificare un elemento della lista restituita da grep (ad esempio in un foreach, in un map o in un altro grep) di fatto modifica l'elemento della lista originale. è qualcosa che di solito si dovrebbe evitare scrivendo codice chiaro.
Consultate anche "map" per una lista composta dai risultati del BLOCCO o dell'ESPR.
Interpreta ESPR come una stringa esadecimale, e ne restituisce il valore corrispondente. (Per convertire stringhe che iniziano con 0, 0x o 0b, date un'occhiata a "oct"). Se ESPR viene omessa, hex() usa $_.
print hex '0xAf'; # stampa '175'
print hex 'aF'; # stessa cosa
Le stringhe esadecimali possono rappresentare solo numeri interi. Le stringhe che causerebbero un overflow generano un avvertimento. A differenza di oct(), hex() non rimuove eventuali spazi bianchi ad inizio stringa. Per mostrare qualcosa come esadecimale, si dia un'occhiata a "printf", "sprintf" o "unpack".
Non esiste una reale funzione import. Si tratta semplicemente di un normale metodo (subroutine) definito (o ereditato) dai moduli che desiderano esportare dei nomi in un altro modulo. La funzione use chiama il metodo import per il package usato. Consultate anche "use", perlmod e Exporter.
La funzione index cerca una stringa in un'altra, ma senza comportarsi in maniera simile ad una wildcard [carattere jolly, NdT], come fa invece una ricerca tramite espressione regolare. Essa restituisce la posizione della prima occorrenza di SOTTOSTR in STR, a partire da POSIZIONE. Se POSIZIONE viene omessa, index inizia a cercare dall'inizio della stringa. La POSIZIONE prima dell'inizio della stringa oppure dopo la sua fine viene trattata come se fosse, rispettivamente, l'inizio o la fine. POSIZIONE ed il valore restituito indicano la posizione a partire da 0 (o qualsiasi valore a cui abbiate impostato la variabile $[, ma non fatelo). Se la sottostringa non viene trovato, index restituisce un'unità meno della base, cioè solitamente -1.
Restituisce la parte intera di ESPR. Se ESPR viene omessa, int() usa $_. Questa funziona non va usata per arrotondare: primo perché tronca verso 0, e secondo perché le rappresentazioni della macchina dei numeri in virgola mobile possono dar luogo a risultati inaspettati. Per esempio, int(-6.725/0.025) generara -268 anziché il corretto -269; ciò è dovuto al fatto che il numero è in realtà qualcosa di simile a -268.99999999999994315658. Di solito, le funzioni sprintf, printf, o POSIX::floor e POSIX::ceil vi saranno più utili di quanto possa esserlo int().
Implementa la funzione di sistema ioctl(2). Probabilmente dovrete prima scrivere:
require "sys/ioctl.ph"; # probabilmente in $Config{archlib}/sys/ioctl.ph
per ottenere le corrette definizioni delle funzioni. Se sys/ioctl.ph non esiste oppure non contiene le corrette definizioni, dovrete scrivervele da soli, basandovi sui file header in C, come ad esempio <sys/ioctl.h>. (C'è uno script Perl chiamato h2ph, fornito assieme al kit Perl, che potrebbe aiutarvi in questo, ma la cosa non è così banale). SCALARE verrà letto e/o scritto a seconda della FUNZIONE, un puntatore al valore della stringa contenuta in SCALARE verrà passato come terzo argomento della reale chiamata a ioctl. (Se SCALARE non ha un valore di stringa ma ne ha uno numerico, verrà passato direttamente tale valore anziché un puntatore al valore della stringa. Per garantire che ciò avvenga, aggiungete uno 0 allo scalare prima di utilizzarlo). Potrebbe risultare necessario ricorrere alle funzioni pack e unpack per manipolare i valori delle strutture utilizzate da ioctl.
Il valore restituito da ioctl (e fnctl) è di seguito descritto:
se il SO restituisce: allora Perl restituisce:
1 valore indefinito
0 stringa "0 ma vera"
qualsiasi altra cosa quel numero
Dunque, Perl restituisce vero in caso di successo e falso in caso di fallimento. In ogni caso potete determinare facilmente il reale valore restituito dal sistema operativo:
$valorerit = ioctl(...) || -1;
printf "Il sistema ha restituito %d\n", $valorerit;
La stringa speciale "0 ma vero" non risente delle proteste di -w sulla conversione impropria dei numeri.
Unisce le stringhe distinte di LISTA in una singola stringa i cui campi sono separati dal valore di ESPR, e restituisce tale nuova stringa.
$record = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
Fate attenzione al fatto che a differenza di split, join non accetta un pattern come primo argomento. Fate il confronto con "split".
Restituisce una lista contenente tutte le chiavi dell'hash indicato. (In contesto scalare, restituisce il numero di chiavi).
Le chiavi sono restituite in ordine apparentemente casuale. Tale ordine casuale sarà soggetto a cambiamenti nelle future versioni di perl, ma è garantito essere lo stesso che restituiscono le funzioni values e each (ponendo che l'hash non sia stato modificato). Per ragioni di sicurezza, a partire dal Perl 5.8.1 l'ordinamento è differente anche tra diverse esecuzioni di Perl (consultate "Algorithmic Complexity Attacks" in perlsec ["Attacchi di Complessità Algoritmica", NdT]).
Come effetto collaterale, la chiamata a keys() reimposta l'iteratore interno dell'HASH (si veda "each"). In particolare, una chiamata a keys() in un contesto vuoto, reimposta l'iteratore senza alcun costo computazionale aggiuntivo.
Ecco ancora un altro modo per stampare le variabili d'ambiente:
@chiavi = keys %ENV;
@valori = values %ENV;
while (@chiavi) {
print pop(@chiavi), '=', pop(@valori), "\n";
}
oppure ordinate per chiave:
foreach $chiave (sort(keys %ENV)) {
print $chiave, '=', $ENV{$chiave}, "\n";
}
I valori restituiti sono copie delle chiavi originali nell'hash, dunque modificare esse non modifica l'hash originale. Fate il confronto con "values".
Per ordinare un hash per valore, dovrete utilizzare una funzione sort. Ecco un ordinamento numerico decrescente di un hash, secondo i suoi valori:
foreach $chiave (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
printf "%4d %s\n", $hash{$chiave}, $chiave;
}
Utilizzata come lvalue [valore a sinistra di un'espressione, NdT], keys vi permette di incrementare il numero di spazi allocati per l'hash indicato. Questo può risultare uno strumento efficiente, se sapete quanto diventerà grande l'hash. (è simile alla pre-estensione di un array tramite l'assegnazione di un numero più grande a $#array). Se scrivete:
keys %hash = 200;
allora %hash avrà almeno 200 spazi allocati per esso, 256 in realtà, poiché arrotonda alla successiva potenza di due. Questi spazi saranno mantenuti anche se scrivete %hash = (), usate undef %hash se volete liberare lo spazio in memoria quando %hash è ancora nello scope. Non potete ridurre il numero di spazi allocati per l'hash utilizzando keys in questo modo (ma non dovrete preoccuparvi del fare ciò per sbaglio, poiché il tentativo non ha alcun effetto collaterale).
Consultate anche each, values e sort.
Invia un segnale ad un elenco di processi. Restituisce il numero di processi a cui il segnale è stato inviato (che non è necessariamente lo stesso numero dei processi terminati).
$conta = kill 1, $figlio1, $figlio2;
kill 9, @morituri;
Se SEGNALE è zero, il processo non riceve nessun segnale. Questo rappresenta un utile modo di verificare che il processo sia ancora attivo e non abbia cambiato il suo UID. Consultate perlport per le note sulla portabilità di questo costrutto.
Diversamente da quanto accade nella shell, se SEGNALE è negativo, vengono terminati gruppi di processi invece di processi (su sistemi basati su System V, un numero di PROCESSO negativo ha lo stesso effetto di terminare gruppi di processi, ma questo non è portabile). Questo significa che generalmente vanno utilizzati segnali positivi, non negativi. Si può anche utilizzare un nome di processo fra virgolette.
Consultate "Signals" in perlipc ["Segnali", NdT] per maggiori dettagli.
Il comando last è come l'istruzione break del C (che viene utilizzata nei loop); esce immediatamente dal loop in questione. Se l'ETICHETTA viene omessa, il comando fa riferimento al ciclo più interno che la racchiude. Il blocco continue, se presente, non viene eseguito:
LINEA: while (<STDIN>) {
last LINEA if /^$/; # esce alla fine degli header
#...
}
last non può essere utilizzato per uscire da un blocco che restituisce un valore, come eval {}, sub {} o do {}, e non dovrebbe essere utilizzato per uscire da un'operazione grep() o map().
Va notato che un blocco, in sé, è semanticamente identico ad un loop che viene eseguito una volta sola. Quindi, last può essere utilizzato per ottenere un'uscita anticipata da un blocco.
Consultate anche "continue" per un esempio di come funzionano last, next e redo.
Restituisce una versione di ESPR con lettere minuscole. Questa é la funzione interna che implementa l'escape \L nelle stringhe tra apici doppi. Rispetta l'LC_CTYPE locale corrente se use locale é attivo. Consultate perllocale e perlunicode per maggiori dettagli sul supporto per il locale e l'Unicode.
Se ESPR viene omessa, lc usa $_.
Restituisce il valore di ESPR con il primo carattere convertito in minuscolo. Questa è la funzione interna che implementa il carattere di escape \l nelle stringhe racchiuse tra apici doppi. Rispetta il locale LC_CTYPE corrente se è stato specificato use locale. Consultate perllocale e perlunicode per maggiori dettagli sul supporto per il locale e l'Unicode.
Se ESPR viene omessa, la funzione usa $_.
Restituisce la lunghezza in caratteri del valore di ESPR. Se ESPR viene omessa, restituisce la lunghezza di $_. Va notato che questa funzione non può essere usata su interi array o hash per scoprire quanti elementi essi abbiano. Per questo, usate rispettivamente scalar @array e scalar keys %hash.
Notate i caratteri: se la ESPR è in Unicode, otterrete il numero di caratteri, non il numero di byte. Per ottenere la lunghezza in byte, usate do { use bytes; length(ESPR) }, consultate bytes.
Crea un nuovo nomefile che è un link al vecchio nomefile. Restituisce vero in caso di successo, falso altrimenti.
Fa la stessa cosa di quello che fa la chiamata di sistema listen. Restituisce vero se ha successo, falso altrimenti. Si veda l'esempio in "Sockets: Client/Server Communication" in perlipc ["Socket: Comunicazione Client/Server", NdT].
In realtà desiderate probabilmente usare my, poiché local non è ciò che la maggior parte delle persone intendono come "locale". Consultate "Private Variables via my()" in perlsub ["Variabili private tramite my()", NdT] per dettagli.
Local modifica le variabili indicate e le rende locali al blocco, file o eval che include la chiamata. Se viene indicato più di un valore, la lista deve essere posta tra parentesi. Consultate ""Temporary Values via local()" in perlsub ["Valori temporanei tramite local()", NdT] per dettagli, incluse le problematiche relative agli array ed agli hash legati [con tie, NdT].
Converte l'ora restituita dalla funzione time in una lista di 9 elementi, con l'ora localizzata al fuso orario locale. è tipicamente usato come segue:
# 0 1 2 3 4 5 6 7 8
($sec,$min,$ore,$giom,$mese,$anno,$gios,$gioa,$oraleg) =
localtime(time);
Tutti gli elementi della lista sono numerici, e derivano direttamente dalla 'struct tm' del C. $sec, $min e $ore sono i secondi, i minuti e le ore dell'orario specificato.
$giom è il giorno del mese, e $mese è il mese stesso, nell'intervallo 0..11, in cui 0 indica Gennaio e 11 Dicembre. Ciò rende facile ottenere il nome di un mese da una lista:
my @abbr = qw( Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic );
print "$abbr[$mese] $giom";
# $mese=9, $giom=18 fornisce "Ott 18"
$anno è il numero di anni a partire dal 1900, non solo le ultime due cifre dell'anno. Ciò significa che $anno è 123 nel 2023. Il modo corretto per ottenere un anno a quattro cifre è semplicemente:
$anno += 1900;
Per ottenere le ultime due cifre dell'anno (ad esempio, '01' in 2001) fate:
$anno = sprintf("%02d", $anno % 100);
$gios è il giorno della settimana, con 0 che indica Domenica e 3 Mercoledì. $gioa è il giorno dell'anno, nell'intervallo 0..364 (o <0..365> negli anni bisestili).
$oraleg assume valore vero se l'orario specificato cade durante l'ora legale, valore falso altrimenti.
Se ESPR viene omessa, localtime() usa l'ora correte (localtime(time)).
In contesto scalare, localtime() restituisce il valore di ctime(3):
$stringa_diadesso = localtime; # es. "Thu Oct 13 04:54:34 1994"
Questo valore scalare non dipende dal locale ma è interno a Perl. Per il GMT invece del tempo locale, utilizzate la funzione interna "gmtime". Consultate anche il modulo Time::Local (per riconvertire secondi, minuti, ore, ... nel valore intero restituito da time()) e le funzioni strftime(3) e mktime(3) del modulo POSIX.
Per ottenere stringhe di data simili, ma dipendenti dal locale, impostate le vostre variabili d'ambiente relative al locale in maniera appropriata (consultate perllocale) e provate ad esempio:
use POSIX qw(strftime);
$stringa_diadesso = strftime "%a %b %e %H:%M:%S %Y", localtime;
# oppure per il GMT formattato in maniera appropriata per il vostro locale:
$stringa_diadesso = strftime "%a %b %e %H:%M:%S %Y", gmtime;
Va notato che gli escape %a e %b, che rappresentano la forma abbreviata del giorno della settimana e del mese dell'anno, possono non essere necessariamente lunghi tre caratteri.
Si consulti "localtime" in perlport per ciò che concerne la portabilità.
Questa funzione pone un lock consultivo su una variabile condivisa oppure su un oggetto referenziato, contenuti in COSA, fino a che il lock non esce dallo scope.
lock() è una "parola chiave debole": questo significa che se avete definito una funzione con questo nome (prima di qualsiasi chiamata ad essa), sarà invece questa funzione ad essere chiamata. (Ad ogni modo, se dichiarate use threads, lock() è sempre una parola chiave). Consultate threads.
Restituisce il logaritmo naturale (base e) di ESPR. Se ESPR è omessa, restituisce il logaritmo di $_. Per ottenere il logaritmo in un'altra base, servitevi dell'algebra di base: il logaritmo in base N di un numero corrisponde al logaritmo naturale di quel numero diviso per il logaritmo naturale di N. Ad esempio:
sub log10 {
my $n = shift;
return log($n)/log(10);
}
Consultate anche "exp" per l'operazione inversa.
Fa le stesse cose della funzione stat (compreso impostare lo speciale filehandle _) ma esegue stat su di un link simbolico invece che sul file al quale il link simbolico punta. Se sul vostro sistema i link simbolici non sono implementati, viene eseguita una normale /stat. Per informazioni molto più dettagliate, consultate la documentazione di "stat".
Se ESPR viene omessa, esegue stat su $_.
L'operatore di match [corrispondenza, NdT]. Si veda perlop.
Valuta il BLOCCO o l'ESPR per ogni elemento della lista (assegnando localmente a $_ ogni elemento) e restituisce la lista di valori costituita dai risultati di ciascuna di queste valutazioni. In un contesto scalare, restituisce il numero il numero totale degli elementi così generati. Valuta il BLOCCO o l'ESPR in un contesto di lista, in maniera tale che ciascuno degli elementi della LISTA può produrre zero, uno o più elementi nel valore restituito.
@caratteri = map(chr, @numeri);
traduce una lista di numeri nei corrispondenti caratteri. E
%hash = map { getkey($_) => $_ } @array;
è solo un modo divertente per scrivere:
%hash = ();
foreach $_ (@array) {
$hash{getkey($_)} = $_;
}
Va notato che $_ è un alias del valore dell'elemento della lista, quindi può essere usato per modificare elementi della LISTA. Benché utile e supportato, può causare risultati bizzarri se gli elementi della LISTA non sono variabili. L'uso di un regolare ciclo foreach per questi scopi sarebbe più chiaro nella maggior parte dei casi. Consultate anche "grep" per un array costituito da quegli elementi della lista originale per i quali la valutazione del BLOCCO o dell'ESPR produce un valore vero.
Con { cominciano sia i blocchi che i riferimenti a hash, quindi map { ... può essere sia l'inizio di map BLOCK LIST che l'inizio di map EXPR, LIST. Poiché perl non guarda avanti alla ricerca della } di chiusura, deve formulare una congettura a proposito di ciò con cui ha a che fare, basandosi su quello che trova subito dopo {. Tipicamente indovina, ma in caso contrario non capirà che qualcosa non va fino a quando non arriverà alla }, trovando una virgola di troppo (o mancante). L'errore sintattico sarà segnalato vicino alla } ma dovrete cambiare qualcosa vicino alla {, ad esempio usare un + unario per aiutare un pochino il perl:
%hash = map { "\L$_", 1 } @array # perl crede sia una ESPR. sbagliato
%hash = map { +"\L$_", 1 } @array # perl crede sia un BLOCCO. giusto
%hash = map { ("\L$_", 1) } @array # anche questo funziona
%hash = map { lc($_), 1 } @array # cosi` come questo
%hash = map +( lc($_), 1 ), @array # questa e` una ESPR e funziona!
%hash = map ( lc($_), 1 ), @array # viene valutato in (1, @array)
oppure, per forzare un costruttore di hash anonimi, usate +{
@tanti_hash = map +{ lc($_), 1 }, @array # e` un'ESPR, quindi ha bisogno della , in fondo
e otterrete una lista di hash anonimi, ciascuno con una sola coppia chiave/valore.
Crea la directory specificata da NOMEFILE, con i permessi specificati da MASK (come se fosse modificata da umask). In caso di successo restituisce vero, altrimenti restituisce falso ed imposta $! (errno). Se omesso, MASK assume valore 0777.
In generale, è meglio creare le directory utilizzando MASK permissive, e poi consentire all'utente di modificarle con il suo umask, piuttosto che fornire una MASK restrittiva e non offrire all'utente alcuna possibilità per renderla più permissiva. L'eccezione a questa regola si ha nel caso in cui il file o la directory debbano essere mantenuti privati (ad esempio file contenenti posta). La voce di perlfunc(1) su umask discute la scelta di una MASK in maniera piuù dettagliata.
Va notato che, in accordo con la specifica POSIX 1003.1-1996, NOMEFILE può avere come suffisso un numero qualsiasi di slash. Alcuni sistemi operativi non gestiscono questa cosa correttamente, quindi Perl rimuove in automatico tutti gli slash alla file di NOMEFILE, facendo contenti tutti.
Chiama la funzione msgctl(2) del System V IPC. Probabilmente dovrete prima scrivere
use IPC::SysV;
per ottenere le corrette definizioni delle costanti. Se CMD è IPC_STAT, allora ARG deve essere una variabile, che conterrà la struttura msqid_ds restituita. I valori restituiti sono gli stessi di ioctl: il valore indefinito in caso di errore, "0 ma vero" in caso di zero, il reale valore restituito negli altri casi. Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::Semaphore.
Chiama la funzione msgget(2) del System V IPC. Restituisce l'id della coda dei messaggi, oppure il valore indefinito se si verifica un errore. Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::Msg.
Chiama la funzione msgrcv del System V IPC, allo scopo di ricevere un messaggio dalla coda ID e memorizzarlo nella variabile VAR, con una dimensione massima del messaggio di DIMENSIONE. È importante notare che, quando un messaggio viene ricevuto, la prima cosa in VAR sarà il tipo del messaggio nella forma di un intero long, seguita dal reale messaggio. Questo impacchettamento può venire aperto con unpack("l! a*"). Questo provoca un taint sulla variabile [il dato in essa contenuto viene indicato come potenzialmente dannoso, NdT]. Restituisce vero in caso di successo, oppure falso se si verifica un errore. Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::SysV::Msg.
Chiama la funzione msgsnd del System V IPC, allo scopo di spedire il messaggio MSG nella coda di messaggi ID. MSG deve iniziare con un intero long nativo che indica il tipo di messaggio, ed essere seguito dalla lunghezza del messaggio effettivo, ed infine dal messaggio stesso. Questo tipo di impacchettamento può essere ottenuto utilizzando pack("l! a*", $tipo, $messaggio). Restituisce vero in caso di successo, o falso se si verifica un errore. Consultate anche la documentazione di IPC::SysV e IPC::SysV::Msg.
Un my dichiara le variabili indicate, come locali (a livello lessicale) nel blocco, file o eval, che include la dichiarazione. Se viene indicata più di una variabile, la lista va messa tra parentesi.
Le precise semantiche e l'interfaccia di TIPO ed ATTR sono ancora in evoluzione. TIPO è al momento legato all'uso della direttiva fields, e gli attributi sono gestiti utilizzando la direttiva attributes oppure, a partire da Perl 5.8.0, anche servendosi del modulo Attribute::Handlers. Consultate "Private Variables via my()" in perlsub ["Variabili private tramite my()", NdT] per dettagli e fields, attributes e Attribute::Handlers.
Il comando next è come l'istruzione continue in C; avvia l'iterazione successiva del ciclo:
LINEA: while (<STDIN>) {
next LINEA if /^#/; # scarta i commenti
#...
}
Va notato che se ci fosse un blocco continue nel precedente esempio, si otterrebbe l'esecuzione anche delle linee scartate. Se l'ETICHETTA viene omessa, il comando fa riferimento al ciclo più interno che la racchiude.
next non può essere usato per uscire da un blocco che restituisce un valore come eval {}, sub {} o do {} e non dovrebbe essere usato per uscire da una operazione di grep() o map().
Va notato che un blocco di per sé è semanticamente identico ad un ciclo che viene eseguito una volta sola. Perciò next uscirà in maniera anticipata da un tale blocco.
Date un'occhiata anche a "continue" per una delucidazione su come funzionano last, next e redo.
Si veda la funzione use, della quale no è l'opposto.
Interpreta ESPR come una stringa ottale, e restituisce il valore corrispondente. (Se per caso ESPR inizia con 0x, viene interpretata come una stringa esadecimale. Se ESPR inizia con 0b, viene interpretata come una stringa binaria. Qualsiasi spazio bianco che faccia da prefisso viene ignorato in tutti e tre i casi). Il seguente codice è in grado di gestire decimali, binari, ottali ed esadecimali nella notazione standard di Perl o di C:
$val = oct($val) if $val =~ /^0/;
Se ESPR viene omessa, oct() usa $_. Per compiere l'operazione inversa (produrre un numero ottale), usate sprintf() o printf():
$permessi = (stat("nomefile"))[2] & 07777;
$permessi_ottali = sprintf "%lo", $permessi;
La funzione oct() è comunemente usata quando una stringa come 644 necessita di essere convertita affinché rappresenti per, esempio, i permessi di un file. (Benché perl converta automaticamente le stringhe in numeri quando necessario, questa conversione automatica usa la base 10).
Apre il file con nome ESPR, e gli associa FILEHANDLE.
(Quella che segue è una documentazione completa di open(): per un'introduzione più semplice prendete in considerazione la lettura perlopentut).
Se FILEHANDLE è una variabile scalare non definita (oppure un elemento di un array o di un hash), le viene assegnato un riferimento ad un filehandle anonimo, diversamente se FILEHANDLE è un'espressione, il suo risultato è usato come nome del filehandle voluto. (Questo potrebbe esser considerato come un riferimento simbolico, in questo caso use strict 'refs' potrebbe non essere efficace).
Se EXPR viene omesso, verrà usata la variabile come scalare dello stesso nome di FILEHANDLE. (Si noti che le variabili lessicali, quelle dichiarate con my, non funzioneranno per questo scopo; in questo caso se usate my, specificate ESPR nella chiamata a open).
Se vengono specificati tre o più argomenti la modalità di apertura e il nome del file sono separati. Se MODE è '<' oppure nulla, il file è aperto in lettura. Se MODE è '>' il file viene troncato e aperto in scrittura, oppure creato se necessario. Se MODE è '>>' il file viene aperto in append mode oppure creato se necessario ["append mode" significa scrittura dalla fine del file, NdT].
Potete mettere un '+' davanti a '>' oppure '<' per indicare che intendete sia leggere che scrivere sul file; per questo '+<' è quasi sempre preferito per aggiornamenti in lettura/scrittura, la modalità '+>' prima troncherà il file. Di norma non potete usare la modalità di lettura/scrittura per aggiornare file di testo, dato che hanno una lunghezza di record non fissa. Controllate l'opzione -i in perlrun per un miglior approccio al problema. Il file viene creato con permessi 0666 modificati dalla umask impostata per il processo.
Questi vari prefissi corrispondono ai parametri mode di fopen(3) 'r', 'r+', 'w', 'w+', 'a' e 'a+'.
Nel caso d'uso a 2 argomenti (e 1 argomento) il MODE e il FILENAME devono essere concatenati (nel modo citato), possibilmente separati da spazi. Non è possibile omettere il MODE in questi casi se si intende usare '<'.
Se il FILENAME inizia per '|' verrà interpretato come un comando al quale gli verrà inviato dell'output come pipe, e se FILENAME finisce per '|' verrà interpretato come un comando che invierà il suo output a noi. Consultate "Using open() for IPC" in perlipc ["Usare open() per IPC", NdT] per altri esempi su questo caso. (Non è ammesso l'uso di open per eseguire un comando e accedervi in scrittura e in lettura, consultate IPC::Open2, IPC::Open3 e "Bidirectional Communication with Another Process" in perlipc ["Comunicazioni bidirezionali con un altro processo", NdT] per delle alternative).
Per tre o più argomenti, se MODO è '|-', il nome del file viene interpretato come un comando al quale gli verrà inviato dell'output come pipe e se MODO è '-|', il nome del file verrà interpretato come un comando che invierà il suo output a noi. Nel caso della versione a 2 argomenti (e 1 argomento), si dovrebbe sostituire il trattino ('-') con il comando. Consultate "Using open() for IPC" in perlipc ["Usare open() per IPC", NdT] per altri esempi su questo caso. (Non è ammesso l'uso di open per eseguire un comando e accedervi in scrittura e in lettura, consultate IPC::Open2, IPC::Open3 e "Bidirectional Communication" in perlipc ["Comunicazioni bidirezionali", NdT] per delle alternative).
Nel caso della versione a tre o più argomenti della apertura delle pipe, se LIST è specificato (ulteriore parametro dopo il nome comando) allora LIST diventa la lista dei parametri da inviare al comando quando invocato, se la piattaforma in uso lo permette. Il significato di open con più di tre argomenti per chiamate diverse dalle pipe non è specificato. Alcuni "layers" sperimentali potrebbero fornire parametri ulteriori per dare significato a LIST.
Nel caso della versione a 2 argomenti (e 1 argomento), l'apertura di '-' significa la lettura di STDIN mentre '>-' l'apertura di STDOUT.
Potete usare i tre parametri per aprire specifici "strati" di IO (altrimenti noti come "disciplines" [letteralmente "ordini, discipline", NdT]) che verranno applicati all'handle, i quali modificano il funzionamento di come input e output vengono processati (consultate open e PerlIO per ulteriori dettagli). Per esempio
open(FH, "<:utf8", "file")
aprirà il file codificato UTF-8 contenente caratteri Unicode, si veda perluniintro. Va notato che se lo strato è specificato nel caso di tre parametri, gli strati impostati di default dalla direttiva open vengono ignorati.
Open restituisce un valore diverso da zero in caso di successo, il valore indefinito diversamente. Se la open presenta una pipe, il valore restituito può essere il PID del processo figlio.
Se si esegue Perl su un sistema che distingue fra file di testo e file binari, controllate "binmode" per alcuni consigli su come gestire questi casi. La chiave di distinzione fra sistemi che richiedono binmode e quelli che non lo richiedono è il loro formato di file di testo. Sistemi come Unix, Mac OS e Plan 9, che delimitano le linee con un singolo carattere, codificato in C come "\n", non richiedono binmode. Gli altri lo richiedono.
Quando si apre un file, non è buona norma continuare la normale esecuzione se la chiamata fallisce, per questa ragione open viene frequentemente usata con die. Anche se die non farà quanto voluto (nel caso di script CGI, dove vorreste ottenere una pagina di errore formattata (ma ci sono dei moduli che possono aiutare con questo problema)) dovreste sempre controllare il valore restituito dalla apertura di un file. Fa eccezione il raro caso quando si intende usare un filehandle NON aperto.
Un caso speciale, la versione a 3 argomenti in modalità lettura/scrittura dove il terzo parametro sia undef:
open(TMP, "+>", undef) or die ...
che apre un filehandle su un file temporaneo anonimo. Inoltre, l'utilizzo di "+<" funziona per simmetria ma dovreste realmente considerare di scrivere prima qualcosa sul file temporaneo. Avrete la necessitè di utilizzare seek() per effettuare la lettura.
A partire dalla versione 5.8.0, il perl è stato compilato usando PerlIO di default. A meno che voi non abbiate cambiato questo aspetto (cioè Configure -Uuseperlio), potete aprire i filehandle in file "in memoria" mantenuti entro scalari Perl tramite:
open($fh, '>', \$variabile) || ..
Tuttavia, se volete riaprire STDOUT oppure STDERR come file "in memoria", prima dovete chiuderli:
close STDOUT;
open STDOUT, '>', \$variabile or die "Impossibile aprire STDOUT: $!";
Esempio:
$ARTICOLO = 100;
open ARTICOLO or die "Impossibile trovare l'articolo $ARTICOLO: $!\n";
while (<ARTICOLO>) {...
open(LOG, '>>/usr/spool/news/twitlog'); # (log e` riservato)
# se la open fallisce, l'output viene perso
open(DBASE, '+<', 'dbase.mine') # aperto per aggiornare
or die "Impossibile aprire 'dbase.mine' per aggiornare: $!";
open(DBASE, '+<dbase.mine') # piu` rapidamente
or die "Impossibile aprire 'dbase.mine' per aggiornare: $!";
open(ARTICLE, '-|', "caesar <$article") # decodifica articolo
or die "Impossibile avviare caesar: $!";
open(ARTICLE, "caesar <$article |") # piu` rapidamente
or die "Impossibile avviare caesar: $!";
open(EXTRACT, "|sort >Tmp$$") # $$ e` il pid del nostro processo
or die "Impossibile avviare sort: $!";
# file in memoria
open(MEMORY,'>', \$var)
or die "Impossibile aprire il file in memoria: $!";
print MEMORY "pippo!\n"; # l'output andra` a finire in $var
# processa la lista degli argomenti dei file insieme con ogni include
foreach $file (@ARGV) {
process($file, 'fh00');
}
sub process {
my($nomefile, $input) = @_;
$input++; # questo e` un incremento di stringa
unless (open($input, $nomefile)) {
print STDERR "Impossibile aprire $nomefile: $!\n";
return;
}
local $_;
while (<$input>) { # si noti l'uso di indirezione
if (/^#include "(.*)"/) {
process($1, $input);
next;
}
#... # qualunque cosa
}
}
Consultate perliol per informazioni dettagliate su PerlIO.
Inoltre potete, nella tradizione della Bourne shell, specificare un EXPR che inizia con '>&', nel qual caso il resto della stringa viene interpretato come un filehandle (o descrittore di file, se è numerico) per essere duplicato (come dup(2)) e aperto. Potete usare & dopo >, >>, <, +>, +>> e +<. La modalità che specificate deve essere uguale alla modalità del filehandle originale. (Duplicare un filehandle non entra nel merito dell'esistenza di precedenti buffer di IO). Se usate la versione a 3 argomenti, potete passare un numero, il nome di un filehandle oppure un normale "riferimento ad un glob".
Ecco uno script che salva, redirige e ripristina STDOUT e STDERR usando diversi metodi:
#!/usr/bin/perl
open my $vecchioout, ">&STDOUT" or die "Impossibile duplicare STDOUT: $!";
open VECCHIOERR, ">&", \*STDERR or die "Impossibile duplicare STDERR: $!";
open STDOUT, '>', "pippo.out" or die "Impossibile redirezionare STDOUT: $!";
open STDERR, ">&STDOUT" or die "Impossibile duplicare STDOUT: $!";
select STDERR; $| = 1; # rendiamolo non bufferizzato
select STDOUT; $| = 1; # rendiamolo non bufferizzato
print STDOUT "stdout 1\n"; # questo funziona
print STDERR "stderr 1\n"; # anche per sottoprocessi
open STDOUT, ">&", $vecchioout or die "Impossibile duplicare \$vecchioout: $!";
open STDERR, ">&VECCHIOERR" or die "Impossibile duplicare VECCHIOERR: $!";
print STDOUT "stdout 2\n";
print STDERR "stderr 2\n";
Se specificate '<&=X', dove X è un numero descrittore di file, oppure un filehandle, allora Perl eseguirà l'equivalente della funzione C fdopen su quel descrittore di file (e non chiamerà dup(2)); questo è un modo d'uso più parsimonioso dei descrittori di file. Per esempio:
# apertura in input, riutilizzando il fileno di $fd
open(FILEHANDLE, "<&=$df")
oppure
open(FILEHANDLE, "<&=", $df)
oppure
# apertura in aggiornamento, utilizzando il fileno di VECCHIOFH
open(FH, ">>&=", VECCHIOFH)
oppure
open(FH, ">>&=VECCHIOFH")
Essere parsimoniosi sui filehandle è utile anche (al di là dell'essere parsimoniosi) per esempio quando qualcosa è dipendente dai descrittori dei file, come per esempio l'uso di lock tramite flock(). Se utilizzate semplicemente open(A, '>>&B'), il filehandle A non avrà lo stesso descrittore di file che ha B e quindi flock(A) non farà un flock(B) e viceversa. Ma con open(A, '>>&=B') il filehandle condividerà lo stesso descrittore di file.
Va notato che se state usando un Perl più vecchio della 5.8.0., Perl userà la fdopen() della libreria C standard per implementare la funzionalità "=". Su molti sistemi Unix, fdopen() fallisce quando dei descrittori di file eccedono un certo valore, tipicamente 255. Per le versioni di Perl 5.8.0 e precedenti, PerlIO è molto spesso la norma.
Potete vedere se il Perl è stato compilato con PerlIO eseguendo perl -V e cercando la linea userperlio=. Se useperlio è define, avete PerlIO, altrimenti no.
Se aprite una pipe col comando '-', cioè sia con '|-' o '-|' con la versione a 2 argomenti (o 1) di open(), allora viene eseguita una fork implicita e restituito il pid del processo figlio per il processo padre, 0 al processo figlio. (Usate defined($pid) per determinare se la open ha avuto successo). Il filehandle si riconduce di norma al padre, ma l'input/output su quel filehandle viene passato attraverso pipe da/per lo STDOUT/STDIN del processo figlio. Nel processo figlio il filehandle non è aperto, l'input/output avviene dal/al nuovo STDIN o STDOUT. Solitamente questo viene usato come il normale open con pipe quando volete esercitare maggior controllo proprio su come viene eseguito il comando pipe, come quando state eseguendo setuid e non si vuole controllare il comando shell per i metacaratteri. Le seguenti triple sono più o meno equivalenti:
open(PIPPO, "|tr '[a-z]' '[A-Z]'");
open(PIPPO, '|-', "tr '[a-z]' '[A-Z]'");
open(PIPPO, '|-') || exec 'tr', '[a-z]', '[A-Z]';
open(PIPPO, '|-', "tr", '[a-z]', '[A-Z]');
open(PIPPO, "cat -n '$file'|");
open(PIPPO, '-|', "cat -n '$file'");
open(PIPPO, '-|') || exec 'cat', '-n', $file;
open(PIPPO, '-|', "cat", '-n', $file);
Nell'ultimo esempio, in ogni blocco di codice viene mostrata la pipe come "list form" [un elenco di parametri, NdT], non supportato da alcuna piattaforma. Una buona regola è: se il vostro sistema operativo ha una vera fork() (in altre parole, se è UNIX) potete usare la list form.
Consultate "Safe Pipe Opens" in perlipc ["Apertura sicura di pipe", NdT] per ulteriori esempi.
A partire dalla versione 5.6.0, Perl tenta di svuotare i buffer, tutti i file aperti in output prima di qualsiasi operazione che potrebbe effettuare il fork, ma questo potrebbe non essere supportato su qualche piattaforma (si veda perlport). Per essere sicuri, dovreste impostare $| ($AUTOFLUSH nel modulo English) oppure chiamare il metodo autoflush() di IO::Handle su ogni handle aperto.
Su sistemi che supportano i flag close-on-exec ["chiuso-su-esecuzione", NdT], il flag sarà impostato per ogni nuovo descrittore di file aperto, come determinato dal valore di $^F. Si veda "$^F" in perlvar.
Chiudere uno qualsiasi dei filehandle di pipe provoca l'attesa del processo padre che il processo figlio finisca, restituendo lo stato in $?.
Il nome del file passato nella chiamata alla open() nella versione con 2 argomenti (o 1) avrà gli spazi in testa e coda eliminati, e i normali caratteri di redirezione verranno onorati. Questa proprietà, nota come "magic open" ["apertura magica", NdT], può spesso essere usata con buoni esiti. Un utente potrebbe specificare un nomefile tipo "rsh cat file |", oppure voi potreste cambiare alcuni particolari nomifile in base alle necessità:
$nomefile =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
open(FH, $nomefile) or die "Impossibile aprire $nomefile: $!";
Usate la versione della open a 3 argomenti per aprire un file che contiene strani caratteri arbitrari,
open(PIPPO, '<', $file);
oppure potrebbe essere necessario proteggere un qualsiasi spazio a inizio o fine nome:
$file =~ s#^(\s)#./$1#;
open(PIPPO, "< $file\0");
(questo potrebbe non funzionare su qualche bizzarro filesystem). Uno potrebbe scegliere, in coscienza, fra la versione magica e la versione a tre argomenti di open():
open IN, $ARGV[0];
permette all'utente di specificare un parametro della forma "rsh cat file |", ma non funziona su un nome file con uno spazio, mentre
open IN, '<', $ARGV[0];
ha esattamente le restrizioni opposte.
Se volete una "vera" open in stile C (consultate open(2) sul vostro sistema), dovrete usare la funzione sysopen, la quale non implica questo genere di "magia" (ma potrebbe usare alcuni differenti filemode rispetto alla open() del Perl, i quali sono mappati alla fopen() del C). Questa è un'altra possibilità per proteggere meglio il vostro nome file dalle interpretazioni. Per esempio:
use IO::Handle;
sysopen(HANDLE, $path, O_RDWR|O_CREAT|O_EXCL)
or die "sysopen $path: $!";
$vecchiofh = select(HANDLE); $| = 1; select($vecchiofh);
print HANDLE "Delle cose $$\n";
seek(HANDLE, 0, 0);
print "Il file contiene: ", <HANDLE>;
Usando il costruttore dal package IO::Handle (oppure una delle delle sue sottoclassi, tipo IO::File oppure IO::Socket), potete generare filehandle anonimi che hanno come scope lo stesso di una qualsiasi variabile che possa contenere riferimenti, e automaticamente chiusi comunque, ogniqualvolta uscite da tale scope:
use IO::File;
#...
sub leggo_miofile_munged {
my $TUTTO = shift;
my $handle = new IO::File;
open($handle, "miofile") or die "miofile: $!";
$primo = <$handle>
or return (); # Qui viene chiuso automaticamente.
mung $primo or die "mung fallito"; # Oppure qui.
return $primo, <$handle> if $TUTTO; # Oppure qui.
$primo; # Oppure qui.
}
Consultate "seek" per qualche dettaglio riguardo la possibilità di mescolare letture e scritture.
Apre una directory chiamata ESPR affinché sia possibile accedere ad essa con readdir, telldir, seekdir, rewinddir e closedir. Restituisce vero se l'operazione ha avuto successo. I DIRHANDLE hanno il loro spazio dei nomi separato da quello dei FILEHANDLE.
Restituisce il valore numerico (la codifica nativa a 8 bit, come ASCII o EBCDIC, o Unicode) del primo carattere di ESPR. Se ESPR viene omessa, la funzione usa $_.
Per il contrario, si veda "chr". Consultate perlunicode e encoding per ulteriori informazioni su Unicode.
our associa un nome elementare con una variabile di package nel corrente package per usarla all'interno dello scope corrente. Quando è in vigore use strict 'vars', our vi permette di dichiarare variabili globali senza qualificarle con i nomi dei package, all'interno dello scope lessicale della dichiarazione our. Così our differisce da "use vars", il cui scope è a livello di package
A differenza di my, che alloca sia dello spazio per una variabile sia associa un nome elementare con quello spazio per un suo uso all'interno dello scope corrente, our associa un nome elementare con una variabile di package nel package corrente, per un suo uso all'interno dello scope corrente. In altre parole, our ha le stesse regole di scope di my, ma non crea necessariamente una variabile.
Se è indicato più di un valore, la lista deve essere inclusa tra parentesi.
our $pippo;
our($pluto, $paperino);
Un dichiarazione our dichiara una variabile globale che sarà visibile su tutto il suo scope lessicale, persino attraverso i limiti di un package. Il package in cui la variabile viene inserita è determinato al momento della dichiarazione, non al momento dell'uso. Ciò significa che è valido il seguente comportamento:
package Pippo;
our $pluto; # dichiara $Pippo::pluto per il resto dello scope lessicale
$pluto = 20;
package Pluto;
print $pluto; # stampa 20, visto che si riferisce a $Pippo::pluto
Sono permesse multiple dichiarazioni our con lo stesso nome all'interno dello stesso scope lessicale, se si trovano all'interno di differenti package. Se si trovano nello stesso package, Perl genererà degli avvertimenti solo se li avete richiesti, proprio come delle multiple dichiarazioni di my. Diversamente da una seconda dichiarazione my, che legherà il nome ad una nuova variabile, una seconda dichiarazione our nello stesso package, nello stesso scope, è solamente ridondante.
use warnings;
package Pippo;
our $pluto; # dichiara $Pippo::pluto per il resto dello scope lessicale
$pluto = 20;
package Pluto;
our $pluto = 30; # dichiara $Pluto::pluto per il resto dello scope lessicale
print $pluto; # stampa 30
our $pluto; # genera un warning ma non ha altri effetti
print $pluto; # stampa ancora 30
Una dichiarazione our può anche avere una lista di attributi associata ad essa.
Le semantiche esatte e l'interfaccia di TIPO ed ATTRIBUTI sono ancora in evoluzione. TIPO è al momento legato all'uso della direttiva fields, a gli attributi sono gestiti utilizzando la direttiva attributes o, a partire da Perl 5.8.0, anche tramite il modulo Attribute::Handlers. Consultate "Private Variables via my()" in perlsub ["Variabili private tramite my()", NdT] per i dettagli e fields, attributes e Attribute::Handlers.
Il solo attributo per our() attualmente riconosciuto è unique, che indica che una singola copia del globale deve essere utilizzata da tutti gli interpreti nel caso il programma stia girando in un ambiente multi-interprete. (Il comportamento predefinito prevede che ogni interprete abbia la sua copia del globale). Esempi:
our @EXPORT : unique = qw(pippo);
our %EXPORT_TAGS : unique = (pluto => [qw(aa bb cc)]);
our $VERSION : unique = "1.00";
Va notato che questo attributo ha anche l'effetto di far sì che il globale diventi in sola lettura quando il primo nuovo interprete viene clonato (per esempio, quando viene creato il primo nuovo thread).
Gli ambienti multi interprete possono esistere tramite l'emulazione di fork() sotto Windows, o incapsulando perl in un'applicazione multi-threaded. L'attributo unique non fa nulla in tutti gli altri ambienti.
Attenzione: l'attuale implementazione di questo attributo opera sui typeglob associati con la variabile; questo significa che our $x : unique ha anche l'effetto di our @x : unique; our %x : unique. Questo potrebbe essere soggetto a cambiamenti.
Prende una LISTA di valori e la converte in una stringa utilizzando le regole fornite da TEMPLATE. La stringa risultante è la concatenazione dei valori convertiti. Solitamente, ogni valore convertito equivale alla sua rappresentazione a livello di elaboratore. Per esempio, sulle macchine a 32 bit, un intero convertito può essere rappresentato da una sequenza di 4 byte.
Il TEMPLATE è una sequenza di caratteri che forniscono l'ordine ed il tipo dei valori, come indicato di seguito:
a Una stringa con dati binari arbitrari, sara` completata da null.
A Una stringa testuale (ASCII), sara` completata da spazi.
Z Una stringa terminata da null (ASCII), sara` completata da null.
b Una stringa di bit (ordine ascendente dei bit all'interno di ciascun byte, come vec()).
B Una stringa di bit (ordine discendente dei bit all'interno di ciascun byte).
h Una stringa esadecimale (nybble basso per primo).
H Una stringa esadecimale (nybble alto per primo).
c Un carattere con segno.
C Un carattere senza segno. Supporta solo i byte. Per l'Unicode, si veda U.
s Un intero short con segno.
S Un intero short senza segno.
(Questo 'short' ['corto', NdT] e` _esattamente_
di 16 bit, il che puo` differire da cio`
che un compilatore C locale chiama 'short'. Se desiderate
degli interi corti della lunghezza nativa, utilizzate
il suffisso '!').
i Un intero con segno.
I Un intero senza segno.
(Questo 'intero' e` di _almeno_ 32 bit. La sua
esatta dimensione dipende da cio` che un
compilatore C locale chiama 'int', e potrebbe persino
essere piu` grande del 'long' descritto di
seguito).
l Un intero long con segno.
L Un intero long senza segno.
(Questo 'long' ['lungo', NdT] e` _esattamente_ di 32 bit, il che
puo` differire da cio` che un compilatore
C locale chiama 'long'. Se desiderate degli interi
lunghi della lunghezza nativa, utilizzate il suffisso
'!').
n Un intero short senza segno in ordine di "rete" (big-endian).
N Un intero long senza segno in ordine di "rete" (big-endian).
v Un intero short senza segno in ordine "VAX" (little-endian).
V Un intero long senza segno in ordine "VAX" (little-endian).
(Questi 'short' e 'long' sono _esattamente_ di 16 bit
ed _esattamente_ di 32 bit, rispettivamente).
q Un quad con segno (64-bit).
Q Un quad senza segno.
(I quad sono disponibili solo se il vostro sistema
supporta gli interi a 64 bit, _e_ se Perl e`
stato compilato per supportarli.
In caso contario verra` generato un errore bloccante).
j Un intero con segno (un intero di Perl, IV).
J Un intero senza segno (un intero senza segno di Perl, UV).
f Un numero in virgola mobile in singola precisione, in formato nativo.
d Un numero in virgola mobile in doppia precisione, in formato nativo.
F Un numero in virgola mobile nel formato nativo nativo
(un numero in virgola mobile interno di Perl, NV).
D Un numero in virgola mobile long in doppia precisione,
in formato nativo.
(I numeri in doppia precisione long sono disponibili
solo se il vostro sistema supporta i numeri lunghi
in doppia precisione, _e_ se Perl e` stato
compilato per supportarli.
In caso contario verra` generato un errore bloccante).
p Un puntatore ad una stringa terminata da null.
P Un puntatore ad una struttura (stringa a lunghezza fissa).
u Una stringa uuencoded.
U Un numero di carattere Unicode. Internamente, e` codificato in UTF-8.
(o UTF-EBCDIC su sistemi EBCDIC).
w Un intero compresso BER (non un BER ASN.1, si consulti perlpacktut per
dettagli). I suoi byte rappresentano un
intero senza segno in base 128, con la cifra piu`
significativa per prima, e con il minore numero di cifre
possibile. L'ottavo bit (il bit alto) viene impostato
su ciascun byte, tranne l'ultimo.
x Un byte null.
X Effettua il backup di un byte.
@ Riempie con null fino ad una posizione assoluta.
( Inizia un gruppo ().
Valgono le seguenti regole:
a, A, Z, b, B, h, H, @, x, X e P, la funziona pack preleverà quel numero di valori da LISTA. Un * come numero di ripetizioni indica di usare tutti gli elementi rimasti, tranne che per @, x, X, dove equivale a 0, e u, dove equivale a 1 (o 45, che è lo stesso). Il numero di ripetizioni può essere racchiuso tra parentesi quadre, come in pack 'C[80]', @arr.
È possibile sostituire il numero di ripetizioni con un template, racchiuso tra parentesi quadre; a questo punto, la lunghezza in byte di questo template viene utilizzata come conteggio delle ripetizioni. Per esempio, x[L] salta un intero long (salta cioè il numero di byte in un intero); il template $t X[$t] $t scompatta [con unpack()), NdT] il doppio di quanto compatti $t. Se il template tra parentesi contiene dei comandi di allineamento (come ad esempio x![d]), la lunghezza compattata viene calcolata come se l'inizio del template avesse l'allineamento massimo possibile.
Quando viene utilizzato con Z, * provoca l'aggiunta di un byte null alla fine (cosicché il risultato compattato sia di un'unità più lungo del byte length dell'elemento).
Il numero di ripetizioni per u viene interpretato come il numero massimo di byte da codificare per ciascuna linea di output, con 0 ed 1 sostituiti da 45.
a, A, e Z prelevano solamente un valore, ma lo compattano come una stringa della lunghezza specificata, completando con null o spazi se necessario. Al momento di scompattare, A rimuove eventuali spazi e null all'inizio, Z rimuove tutto dopo il primo null, e a restituisce i dati così come sono. Per compattare, a e Z sono equivalenti.
Se il valore-da-compattare è troppo lungo, esso viene troncato. Se è troppo lungo e viene fornito esplicitamente un conteggio, Z compatta solo $conteggio-1 byte, seguiti da un null. Dunque, Z compatta sempre un null al termine della stringa, in qualsiasi circostanza.
b e B compattano una stringa lunga il numero di bit specificato. Ciascun byte dell'input di pack() genera un bit del risultato. Ogni bit del risultato è basato sul bit meno significativo del byte di input corrispondente, cioè con ord($byte)%2. In particolare i byte "0" e "1" generato i bit 0 e 1, e così fanno i byte "\0" e "\1".
A partire dall'inizio della stringa in input a pack(), ciascun gruppo di 8 byte viene convertito in 1 byte di output. Con il formato b, il primo byte del gruppo di 8 determina il bit meno significativo di un byte, mentre con il formato B determina quello più significativo.
Se la lunghezza della stringa in input non è divisibile esattamente per 8, la parte rimanente viene compattata come se la stringa in input fosse completata di byte null alla fine. In maniera analoga, al momento di utilizzare unpack() i bit "extra" vengono ingoiati.
Se la stringa in input a pack() è più lunga di quanto necessario, i byte in più vengono ignorati. Un * come conteggio delle ripetizioni di pack() indica di utilizzare tutti i byte dell'input. Al momento di utilizzare unpack() i bit sono convertiti in una stringa di "0" e "1".
h e H compattano una stringa lunga il numero di nybble (gruppi di 4 bit, rappresentati come cifre esadecimali, 0-9a-f) specificato.
Ciascun byte in input a pack() genera 4 bit del risultato. Per i byte non alfabetici, il risultato è basato sui 4 bit meno significativi del byte in input, cioè come in ord($byte)%16. In particolare, i byte "0" e "1" generano nybble 0 e 1, così come i byte "\0" e "\1". Per i byte "a".."f" e "A".."F" il risultato è compatibile con le solite cifre esadecimali, dunque "a" e "A" generano entrambi il nybble 0xa==10. Il risultato per i byte "g".."z" e "G".."Z" non è ben definito.
A partire dall'inizio della stringa in input a pack(), ciascuna coppia di byte viene convertita in 1 byte dell'output. Con il formato h il primo byte della coppia determina il nybble meno significativo del byte il output, e con il formato H esso ne determina il nybble più significativo.
Se la lunghezza della stringa in input non è pari, allora essa viene completata con un byte null alla fine. In maniera analoga, al momento dell'utilizzo di unpack() i nybble "extra" vengono ignorati.
Se la stringa in input a pack() è più lunga del necessario, i byte in più vengono ignorati. Un * come conteggio delle ripetizioni di pack() indica di utilizzare tutti i byte dell'input. Al momento di utilizzare unpack() i bit sono convertiti in una stringa di cifre esadecimali.
p compatta un puntatore ad una stringa terminata da null. Siete responsabile dell'assicurarvi che la stringa non sia un valore temporaneo (che può potenzialmente essere deallocato prima che utilizziate il risultato compattato). Il tipo P compatta un puntatore ad una struttura della dimensione indicata dalla lunghezza. Viene creato un puntatore a NULL che il corrispondente valore per p o P è undef. Un comportamento simile si ha con unpack()./ permette di compattare e scompattare stringhe in cui la struttura compattata contiene un conteggio di byte seguito dalla stringa stessa. Dovete scrivere lunghezza-elemento/stringa-elemento.
La lunghezza-elemento può essere qualsiasi lettera di template di pack, e descrive come è compattato il valore di lunghezza. Quelle di utilizzo più frequente sono quelle di compattamento degli interi, quali n (per stringhe Java), c<w> (per ASN.1 o SNMP) e N (per Sun, XDR).
Per pack, la stringa-elemento deve, al momento, essere "A*", "a*" oppure "Z*". Con unpack la lunghezza della stringa è ottenuta da lunghezza-elemento, ma se inserite il carattere '*' viene ignorata. Per tutti gli altri codici, unpack applica il valore della lunghezza all'elemento successivo, che non deve avere un conteggio delle ripetizioni.
unpack 'C/a', "\04Gurusamy"; restituisce 'Guru'
unpack 'a3/A* A*', '007 Bond J '; restituisce (' Bond','J')
pack 'n/a* w/a*','hello,','world'; restituisce "\000\006hello,\005world" [ciao mondo, NdT]
La lunghezza-elemento non viene restituita esplicitamente da unpack.
L'aggiunta di un conteggio a lunghezza-elemento non è probabilmente di alcuna utilità, a meno che la lettera non sia A, a o Z. Compattare con una lunghezza-elemento di a o Z può causare l'inserimento di caratteri "\000", che Perl non considera legali all'interno delle stringhe numeriche.
s, S, l e L possono essere immediatamente seguiti da un suffisso !, che indica che essi sono short o long nativi, come potete vedere sopra, ad esempio un l solitario indica esattamente 32 bit, mentre il long nativo (come è considerato dal compilatore C locale) può essere più grande. Questo è un problema soprattutto nei sistemi a 64-bit. Potete controllare se l'utilizzo di ! crea qualche differenza in questa maniera
print length(pack("s")), " ", length(pack("s!")), "\n";
print length(pack("l")), " ", length(pack("l!")), "\n";
Anche i! e I! funzionano, ma solo per questioni di completezza; essi sono identici a i e I.
Le reali dimensioni (in byte) degli short, int, long e long long nativi sui sistemi dove Perl è stato compilato sono disponibili anche tramite Config:
use Config;
print $Config{shortsize}, "\n";
print $Config{intsize}, "\n";
print $Config{longsize}, "\n";
print $Config{longlongsize}, "\n";
($Config{longlongsize} risulterà non definito se il vostro sistema non supporta i long long).
s, S, i, I, l, L, j e J sono intrinsecamente non portabili tra diversi processori e sistemi operativi, poiché essi obbediscono all'ordine dei byte ed al tipo di endian locale. Per esempio, un intero di 4 byte 0x12345678 (305419896 in decimale) viene ordinato nativamente (ordinato e gestito dai registri della CPU) in byte come:
0x12 0x34 0x56 0x78 # big-endian
0x78 0x56 0x34 0x12 # little-endian
Fondamentalmente, le CPU Intel e VAX sono little-endian, mentre tutti gli altri, ad esempio Motorola m68k/88k, PPC, Sparc, HP PA, Power, e Cray, sono big-endian. Alpha e MIPS possono essere entrambi: Digital/Compaq li usava/usa in modalità little-endian; SGI/Cray li usa in modalità big-endian.
I nomi 'big-endian' e 'little-endian' sono riferimenti fumettistici al classico "Gulliver's Travels" ["I viaggi di Gulliver", NdT] (attraverso il foglio "On Holy Wars and a Plea for Peace" di Danny Cohen, USC/ISI IEN 137, April 1, 1980) ["Sulle guerre sante ed un appello per la pace", NdT] e le abitudini dei Lillipuziani per quanto riguarda il mangiare le uova.
Alcuni sistemi possono avere un ordine dei byte più strano, come:
0x56 0x78 0x12 0x34
0x34 0x12 0x78 0x56
Potete conoscere la preferenza del vostro sistema con:
print join(" ", map { sprintf "%#02x", $_ }
unpack("C*",pack("L",0x12345678))), "\n";
L'ordine dei byte sul sistema dove Perl è stato compilato è inoltre disponibile tramite Config:
use Config;
print $Config{byteorder}, "\n";
I byteorder '1234' e '12345678' sono little-endian, '4321' e '87654321' sono big-endian.
Se desiderate degli interi compattati portabili, utilizzati i formati n, N, v, e V: la loro dimensione e tipo di endian sono conosciuti. Consultate anche perlport.
Va notato che Perl usa i double internamente per tutti i calcoli numerici, e la conversione da double a float e viceversa causa una perdita di precisione (ad esempio, unpack("f", pack("f", $pippo)) non è generalmente equivalente a $pippo).
U, la stringa risultante verrà trattata come codificata in Unicode. Potete forzare la codifica UTF8 su una stringa inserendo un U0 iniziale, ed i byte che seguono saranno interpretati come caratteri Unicode. Se non volete che ciò accada, potete far iniziare il vostro schema con C0 (o qualsiasi altra cosa) per forzare Perl a non codificare in UTF8 la vostra stringa, facendo poi seguire a ciò un U* da qualche parte nel vostro schema.'x' quando state compattando. Non c'è alcun modo in cui pack() ed unpack() possono sapere dove vanno o da dove vengono i byte. Quindi, pack (e unpack) gestisce il suo output ed input come fossero delle pure sequenze di byte./. All'interno di ogni ripetizione di un gruppo, il posizionamento tramite @ fa ripartire di nuovo da 0. Quindi, il risultato di
pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
è la stringa "\0a\0\0bc".
x ed X accettano il modificatore !. In questo caso si comportano come comandi di allineamento; saltano avanti e indietro alla posizione allineata più vicina ad un multiplo di un numero di byte pari a conteggio. Per esempio, per utilizzare pack() o unpack() su una struct {char c; double d; char cc[2]} del C, potreste dover utilizzare il template C x![d] d C[2]; questo assume che i double siano allineati alla dimensione dei double.
Per i comandi di allineamento, un conteggio di 0 equivale ad un conteggio di 1; entrambi non risultano in alcuna operazione.
# e termina con la fine della linea. Per separate i codici compattati gli uni dagli altri, possono essere utilizzati degli spazi, ma deve seguire immediatamente un modificatore ! ed un numero di ripetizioni."". Se TEMPLATE richiede meno argomenti per pack() di quanti ne siano stati in realtà forniti, gli argomenti in più vengono ignorati.Esempi:
$pippo = pack("CCCC",65,66,67,68);
# pippo eq "ABCD"
$pippo = pack("C4",65,66,67,68);
# stessa cosa
$pippo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
# stessa cosa con le lettere cerchiate Unicode
$pippo = pack("ccxxcc",65,66,67,68);
# pippo eq "AB\0\0CD"
# nota: gli esempi qui sopra che utilizzano "C" e "c" sono validi
# solo su sistemi ASCII o derivati come ISO Latin 1 e UTF-8.
# In EBCDIC il primo esempio diventerebbe
# $pippo = pack("CCCC",193,194,195,196);
$pippo = pack("s2",1,2);
# "\1\0\2\0" su little-endian
# "\0\1\0\2" su big-endian
$pippo = pack("a4","abcd","x","y","z");
# "abcd"
$pippo = pack("aaaa","abcd","x","y","z");
# "axyz"
$pippo = pack("a14","abcdefg");
# "abcdefg\0\0\0\0\0\0\0"
$pippo = pack("i9pl", gmtime);
# un vera struct tm (almeno, sul mio sistema)
$utmp_template = "Z8 Z8 Z16 L";
$utmp = pack($utmp_template, @utmp1);
# una struct utmp (in stile BSD)
@utmp2 = unpack($utmp_template, $utmp);
# "@utmp1" eq "@utmp2"
sub bintodec {
unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
$pippo = pack('sx2l', 12, 34);
# short 12, completamento con due zeri, long 34
$pluto = pack('s@4l', 12, 34);
# short 12, riempito con zeri fino alla posizione 4, long 34
# $pippo eq $pluto
Lo stesso template può in genere venire usato anche in unpack().
Dichiara l'unità di compilazione come appartenente allo spazio dei nomi specificato. Lo scope della dichiarazione del package parte dalla dichiarazione stessa fino alla fine del blocco, file, o eval che la include (esattamente come per l'operatore my). Tutti gli identificatori dinamici non esplicitamente qualificati apparterranno a questo spazio dei nomi. Un'istruzione che dichiara un package influisce solo sulle variabili dinamiche, incluse quelle dichiarate con local, ma non su quelle lessicali, cioè create con my. Tipicamente, package dovrebbe essere la prima dichiarazione in un file che viene incluso con l'operatore require o user. Potete passare ad un package in più di un punto; tale dichiarazione determina semplicemente quale tabella dei simboli viene usata dal compilatore per la fine del blocco in cui ci trova. Potete far riferimento a variabili e filehandle in altri package anteponendovi il nome del package ed un doppio simbolo di due punti: $Package::Variable. Se il nome del package è vuoto, viene considerato il package main. Dunque, $::sail equivale a $main::sail (ed anche a $main'sail, sintassi che ancora si vede in certo codice vecchio).
Se SPAZIONOMI viene omesso, allora non viene dichiarato alcun package corrente, e tutti gli identificatori devono essere pienamente qualificati, oppure essere lessicali. Comunque, è fortemente sconsigliato non dichiarare uno spazio dei nomi. Ciò potrebbe infatti causare un comportamento inaspettato del vostro programma, o persino un crash in alcune versioni di Perl. La forma senza SPAZIONOMI è considerata obsoleta, e verrà rimossa a partire da una versione a venire.
Consultate "Packages" in perlmod per maggiori informazioni sui package, sui moduli, e sulle classi. Consultate perlsub per ulteriori informazioni sullo scope.
Apre una coppia di pipe connesse, come fa la corrispondente chiamata di sistema. Va notato che se impostate un ciclo di processi connessi tramite pipe, può avvenire uno stallo anche se siete molto prudenti. In aggiunta, notate che le pipe del Perl utilizzando il buffer di IO, dunque potreste aver bisogno di impostare $| per svuotare il vostro HANDLEDISCRITTURA dopo ogni comando, a seconda dell'applicazione.
Consultate IPC::Open2, IPC::Open3 e "Bidirectional Communication" in perlipc ["Comunicazione Bidirezionale, NdT] per esempi di cose come queste.
Sui sistemi che supportano sui file un flag close-on-exec [chiudi-su-esecuzione, NdT], il flag sarà impostato per il descrittore di file appena aperto, come determinato dal valore di $^F. Si veda "$^F" in perlvar.
Rimuove e restituisce l'ultimo valore dell'array, accorciandolo di un elemento. Ha un effetto simile a:
$ARRAY[$#ARRAY--]
Se non ci sono elementi nell'array, restituisce il valore indefinito (per quanto, questo possa accadere anche in altri casi). Se ARRAY viene omesso, rimuove l'ultimo elemento dall'array @ARGV nel corpo principale del programma, e dall'array @_ nelle subroutine, proprio come shift.
Restituisce la posizione per la variabile in questione, per la quale l'ultima ricerca m//g ha trovato qualcosa (se la variabile non è specificata, viene usata $_). Va notato che 0 è un valido scostamento del match. undef indica che la posizione della ricerca è stata reimpostata (di solito a causa del fallimento di un match ma può anche essere perché non è stato ancora effettuato alcun match sullo scalare). pos accede direttamente alla locazione usata dal motore delle espressioni regolari per immagazzinare lo scostamento, dunque fare un assegnamento a pos cambierà lo scostamento e influenzerà la \G zero-width assertion [asserzione di ampiezza zero, NdT] nelle espressioni regolari. Il match non reimposta lo scostamento a causa di un m//gc fallito, il ritorno da pos non cambierà nemmeno in questo caso. Consultate perlre e perlop.
Stampa una stringa oppure una lista di stringhe. Restituisce vero in caso di successo. FILEHANDLE può essere una variabile scalare, nel qual caso deve contenere il nome o un riferimento al filehandle, introducendo quindi un livello di accesso non diretto al filehandle. (NOTA: Se FILEHANDLE è una variabile, ed il successivo simbolo è un termine, esso può venire erroneamente interpretato come un operatore, a meno che non inseriate un + o utilizziate le parentesi attorno agli argomenti). Se FILEHANDLE viene omesso, la stampa viene direzionata all'output standard (o all'ultimo canale di output selezionato, consultate "select"). Se anche LISTA viene omessa, stampa $_ al canale di output correntemente selezionato. Per impostare il canale di output a qualcosa di diverso da STDOUT, utilizzate l'operazione select. Il valore corrente di $, (se impostato) viene stampato come separatore di ciascun elemento di LISTA. Il valore corrente di $\ (se impostato) viene stampato dopo che l'intera LISTA è stata stampata. Poiché print accetta una LISTA, ogni cosa contenuta in tale LISTA viene valutata in contesto di lista, ed ogni subroutine che chiamate si ritroverà una o più d'una delle sue espressioni valutate in contesto di lista. State anche attenti a non far seguire una parentesi di apertura alla parola chiave print, a meno che non desideriate terminare gli argomenti da stampare con la corrispondente parentesi di chiusura, inserite un + o mettere parentesi attorno a tutti gli argomenti.
Va notato che se tenete i FILEHANDLE in un array, o comunque usate delle espressioni più complesse di una semplice variabile scalare per accederli, dovete usare un blocco che restituisca il filehandle:
print { $files[$i] } "cose da stampare\n";
print { $OK ? STDOUT : STDERR } "cose da stampare\n";
Equivalente a print FILEHANDLE sprintf(FORMATO, LISTA), tranne per il fatto che $\ (il separatore di record dell'output) non viene aggiunto. Il primo argomento della lista viene interpretato come il formato per printf. Si veda sprintf per una spiegazione dell'argomento formato. Se use locale è stato attivato, il carattere utilizzato per il punto decimale nella formattazione dei numeri reali è influenzato dal locale LC_NUMERIC. Consultate perllocale.
Si raccomanda di stare attenti a non cadere nella trappola di usare printf quando un semplice print andrebbe bene. L'istruzione print è più efficiente e meno soggetta ad errori.
Restituisce il prototipo di una funzione come stringa (oppure undef se la funzione non ha prototipo). FUNZIONE è un riferimento a, oppure il nome di una funzione di cui volete recuperare il prototipo.
Se FUNZIONE è una stringa che inizia con CORE::, quello che resta viene considerato il nome di una funzione interna del Perl. Se la funzione interna non può essere ridefinita (come qw//) o i suoi argomenti non possono essere espressi mediante un prototipo (come system) restituisce undef dato che la funzione interna non si comporta proprio come una funzione Perl. Altrimenti, viene restituita la stringa che descrive il prototipo equivalente.
Tratta ARRAY come uno stack, e aggiunge i valori di LISTA alla fine di ARRAY. La lunghezza di ARRAY viene aumentata della lunghezza di LISTA. Ha lo stesso effetto di
for $valore (LISTA) {
$ARRAY[++$#ARRAY] = $valore;
}
ma è più efficiente. Restituisce il numero di elementi che sono nell'array dopo l'esecuzione della push.
Sono delle virgolette generalizzate. Consultate "Regexp Quote-Like Operators" in perlop ["Operatori analoghi a quelli di quoting delle espressioni regolari", NdT].
Restituisce il valore di ESPR, con tutti i caratteri non-"parola" preceduti da un backslash. (Il che significa che tutti i caratteri che non rientrano in /[A-Za-z_0-9]/ saranno preceduti da un backslash nella stringa restituita, indipendentemente da qualsiasi impostazione del locale). Questa è la funzione interna che implementa il \Q all'interno delle stringhe delimitate da doppi apici.
Se ESPR viene omesso, quotemeta() usa $_.
Restituisce un numero razionale casuale maggiore o uguale a 0 e minore del valore di ESPR. (ESPR dovrebbe essere positivo). Se ESPR viene omesso, viene usato il valore 1. Attualmente una ESPR con valore 0 viene trattata in maniera speciale, come se fosse 1; questo non è stato documentato prima di perl 5.8.0 ed è soggetto a cambiamenti nelle prossime versioni di perl. srand viene chiamata automaticamente se non è già stato fatto. Consultate anche srand.
Applicate int() al valore restituito da rand() se volete numeri interi casuali anziché numeri razionali casuali. Per esempio,
int(rand(10))
restituisce un intero casuale tra 0 e 9, estremi compresi.
(Nota: Se la vostra funzione rand continua a restituire numeri troppo grandi o troppo piccoli, allora la vostra versione di Perl è stata probabilmente compilata con un numero sbagliato di RANDBITS).
Tenta di leggere LUNGHEZZA caratteri di dati nella variabile SCALARE dal FILEHANDLE specificato. Restituisce il numero di caratteri che sono stati letti, 0 alla fine del file, o il valore indefinito se si è verificato un errore (in quest'ultimo caso, viene anche impostata $!). La lunghezza di SCALARE sarà aumentata o diminuita in maniera che l'ultimo carattere effettivamente letto sia l'ultimo carattere dello scalare dopo la lettura.
Può essere indicato uno SCOSTAMENTO per posizionare i dati letti in qualche altro posto in SCALARE piuttosto che all'inizio. Un OFFSET negativo indica la posizione specificata da tanti caratteri quanti quelli specificati, contando all'indietro a partire dalla fine della stringa. Un OFFSET maggiore della lunghezza di SCALAR fa sì che la stringa sia completata con dei byte "\0" fino alla lunghezza richiesta, prima che il risultato della read venga aggiunto in coda.
La chiamata è effettivamente implementata in termini di chiamata a fread(), del Perl o del sistema operativo. Per una vera chiamata di sistema read(2), si veda sysread.
Notate i caratteri: a seconda dello stato del filehandle, possono essere letti byte (8-bit) o caratteri. Di default tutti i filehandle operano su byte, ma se ad esempio il filehandle è stato aperto con il layer di I/O :utf8 (si veda "open" e la direttiva open, open), le operazioni di I/O opereranno su caratteri, non su byte. In maniera analoga per la direttiva :encoding: in quel caso può essere letto pressoché qualsiasi carattere.
Restituisce il prossimo elemento della directory aperta tramite opendir. Se usato in un contesto lista, restituisce tutti gli elementi rimanenti nella directory. Se non si sono più elementi, restituisce il valore indefinito in contesto scalare oppure una lista nulla in contesto lista.
Se avete in mente di utilizzare i valori restituiti da readdir per dei test su file, fareste meglio ad anteporre la directory in questione. Altrimenti, visto che non viene cambiata la directory corrente (chdir) nella directory che si sta leggendo, potreste stare effettuando il test sul file sbagliato.
opendir(DIR, $una_dir) || die "non posso aprire la dir $una_dir: $!";
@punti = grep { /^\./ && -f "$una_dir/$_" } readdir(DIR);
closedir DIR;
Legge dal filehandle il cui typeglob è contenuto in ESPR. In contesto scalare, ogni chiamata legge e restituisce la prossima linea, fino a quando la fine del file non viene raggiunta, dopodiché le chiamate successive restituiscono il valore indefinito. In contesto lista, legge il file fino alla fine e restituisce una lista di linee. Va notato che la nozione di "linea" dipende da ciò che è stato definito con $/ o $INPUT_RECORD_SEPARATOR [record separatore di input, NdT]. Si veda "$/" in perlvar.
Quando $/ è stato impostato a undef, e readline() viene chiamato in contesto scalare (ossia in slurp mode [modalità slurp, NdT]) e se il file è vuoto, restituisce '' la prima volta, e undef le volte successive.
Questa è la funzione utilizzata internamente dall'implementazione dell'operatore <ESPR>, ma può essere usata direttamente. L'operatore <ESPR> viene discusso in dettaglio in "I/O Operators" in perlop ["Operatori di I/O", NdT].
$line = <STDIN>;
$line = readline(*STDIN); # stessa cosa
Se readline incontra un errore del sistema operativo, $! verrà impostato con il messaggio d'errore corrispondente. Può essere utile controllare $! quando state leggendo dai filehandle di cui non vi fidate, come tty, oppure un socket. Il seguente esempio usa readline in forma di operatore, e svolge i passi necessari ad assicurarsi che readline sia andato a buon fine.
for (;;) {
undef $!;
unless (defined( $linea = <> )) {
die $! if $!;
last; # raggiunto EOF
}
# ...
}
Restituisce il valore di un link simbolico, se i link simbolici sono implementati. Se non lo sono, restituisce un errore bloccante. Se c'è qualche errore di sistema, restituisce il valore indefinito e assegna $! (errno). Se ESPR viene omessa, essa usa $_.
ESPR viene eseguita come un comando di sistema. Viene restituito lo standard output del comando che viene raccolto. In un contesto scalare, restituisce una singola (potenzialmente multi linea) stringa. In un contesto di lista, restituisce una lista di linee (comunque si abbiano definite le linee con $/ o $INPUT_RECORD_SEPARATOR [record separatore di input, NdT]). Questa è la funzione interna che implementa l'operatore qx/ESPR/, ma può essere usata direttamente. L'operatore qx/ESPR/ viene discusso con maggiore dettaglio in "I/O Operators" in perlop ["Operatori di I/O", NdT].
Riceve un messaggio su di un socket. Tenta di ricevere dati per un numero di caratteri pari a LUNGHEZZA nella variabile SCALARE dallo specifico filehandle del SOCKET. SCALARE sarà incrementato o ridotto dalla lunghezza effettivamente letta. Prende gli stessi flag della chiamata di sistema che ha lo stesso nome. Restituisce gli indirizzi di colui che invia se il protocollo del SOCKET lo supporta; altrimenti restituisce una stringa vuota. Se c'è un errore, restituisce il valore indefinito. Questa chiamata viene effettivamente implementata in termini della chiamata di sistema recvfrom(2). Consultate "UDP: Message Passing" in perlipc ["UDP: Passaggio di messaggi", NdT] per degli esempi.
Notate i caratteri: dipendentemente dallo stato del socket, vengono ricevuti sia byte (di 8-bit) che caratteri. Di default, tutti i socket operano su byte ma per esempio se il socket è stato modificato usando binmode() per operare con lo strato di I/O :utf8 (si veda la direttiva open, open), lo I/O opererà su caratteri Unicode codificati UTF-8, non su byte. In maniera analoga per la direttiva :encoding: in quel caso può essere letto più o meno qualsiasi carattere.
Il comando redo fa ripartire il blocco del ciclo senza valutare di nuovo l'espressione condizionale. Il blocco continue, se presente, non viene eseguito. Se l'ETICHETTA viene omessa, il comando si riferisce al ciclo più interno che lo include. Sono quei programmi che vogliono ingannare loro stessi a proposito dell'input, ad usare di solito questo comando:
# un semplice programma che rimuove i commenti da codice Pascal
# (attenzione: si assume che le stringhe non contengano { oppure } )
LINE: while (<STDIN>) {
while (s|({.*}.*){.*}|$1 |) {}
s|{.*}| |;
if (s|{.*| |) {
$anteriore = $_;
while (<STDIN>) {
if (/}/) { # fine del commento?
s|^|$anteriore\{|;
redo LINE;
}
}
}
print;
}
redo non può essere usata per fare rieseguire un blocco che restituisce un valore, come eval {}, sub {} oppure do {}, e non dovrebbe essere usata per uscire da una operazione di grep() o map().
Va notato che un blocco di per sé è semanticamente identico ad un ciclo che viene eseguito una volta sola. Dunque redo all'interno di un tale blocco sarà effettivamente trasformato in un costrutto iterativo.
Consultate anche "continue" per una illustrazione di come lavorano last, next e redo.
Restituisce un valore vero se ESPR è un riferimento, falso altrimenti. Se ESPR viene omessa, utilizza $_. Il valore restituito dipende dal tipo di cosa alla quale il riferimento fa riferimento. I tipi interni sono:
SCALAR
ARRAY
HASH
CODE
REF
GLOB
LVALUE
Se l'oggetto referenziato è un'istanza di una classe, viene restituito il nome di package. Si può pensare a ref come ad un operatore typeof.
if (ref($r) eq "HASH") {
print "r e` un riferimento ad un hash.\n";
}
unless (ref($r)) {
print "r non e` proprio un riferimento.\n";
}
Consultate anche perlref.
Cambia il nome di un file; l'eventuale file NUOVONOME già esistente viene sovrascritto. Restituisce vero in caso di successo, falso negli altri casi.
Il comportamente di questa funzione varia in maniera piuttosto casuale a seconda dell'implementazione del vostro sistema. Per esempio, di solito non funziona se utilizzata attraverso file system diversi, anche se il comando di sistema mv a volte compensa questa carenza. Altre restrizioni includono il funzionamento o meno su directory, file aperti, o file preesistenti. Per i dettagli, controllate perlport e la manpage rename(2) o l'equivalemente sulla documentazione del vostro sistema.
Richiede una versione di Perl specificata da VERSIONE, o richiede alcune semantiche specificate da ESPR oppure da $_ se ESPR non viene fornita.
VERSIONE può essere sia un argomento numerico come 5.006, che viene poi confrontato con $], oppure un valore testuale nella forma di v5.6.1, che viene poi confrontato con $^V (conosciuto anche come $PERL_VERSION). Se VERSIONE è più grande della versione dell'interprete Perl corrente, viene prodotto un errore bloccante al momento dell'esecuzione. Confrontate require con "use", che può compiere un controllo di questo tipo al momento della compilazione.
In genere, bisognerebbe evitare di specificare VERSIONE come un valore testuale nella forma v5.6.1, poiché ciò causa, con versioni vecchie del Perl che non supportano questa sintassi, dei messaggi di errore fuorvianti. Al suo posto dovrebbe essere usata la versione numerica.
require v5.6.1; # controllo di versione al momento dell'esecuzione
require 5.6.1; # uguale
require 5.006_001; # uguale; preferibile per compatibilitE<agrave> all'indietro
Usata diversamente, require richiede che un file di libreria esterno venga incluso, se non lo è stato in precedenza. Il file viene incluso con il meccanismo do-FILE, che essenzialmente è una variante di eval. Ha semantiche simili alla seguente subroutine:
sub require {
my ($nomefile) = @_;
if (exists $INC{$nomefile}) {
return 1 if $INC{$nomefile};
die "Compilazione fallita nel require";
}
my ($nomefilevero,$risultato);
ITER: {
foreach $prefisso (@INC) {
$nomefilevero = "$prefisso/$nomefile";
if (-f $nomefilevero) {
$INC{$nomefile} = $nomefilevero;
$risultato = do $nomefilevero;
last ITER;
}
}
die "Non trovo $nomefile in \@INC";
}
if ($@) {
$INC{$nomefile} = undef;
die $@;
} elsif (!$risultato) {
delete $INC{$nomefile};
die "$nomefile non ha restituito un valore vero";
} else {
return $risultato;
}
}
Va notato che il file non può venire incluso due volte specificando lo stesso nome.
Il file deve restituire un valore vero come ultima istruzione, per indicare il successo dell'esecuzione di qualsiasi codice di inizializzazione, dunque è consuetudine terminare tale file con 1;, a meno che non si sia sicuri che restituisca vero in ogni caso. Tuttavia, la cosa migliore è mettere l'1;, in caso aggiungiate altre istruzioni in un secondo momento.
Se ESPR è una bareword (*), require presume un'estensione ".pm" e sostituisce per voi "::" con "/" nel nome del file, in modo da rendere facile il caricamento dei moduli standard. Questo modo di caricare i moduli non comporta rischi di alterazione dello spazio dei nomi.
In altre parole, se provate questo:
require Pippo::Pluto; # una splendida bareword
La funzione require cercherà in realtà il file "Pippo/Pluto.pm" nelle directory specificate nell'array @INC.
Ma se provate questa:
$class = 'Pippo::Pluto';
require $class; # $class non e` una bareword
#oppure
require "Pippo::Pluto"; # non e` una bareword per via delle ""
La funzione require cercherà il file "Pippo::Pluto" nell'array @INC e si lamenterà di non riuscirvi a trovare "Pippo::Pluto". In questo caso potete scrivere:
eval "require $class";
Ora che avete capito come require cerca i file nel caso di un argomento bareword, c'è una piccola ulteriore funzionalità che ha luogo dietro le quinte. Prima che require si metta a cercare una estensione ".pm", cercherà prima un nomefile con una estensione ".pmc". Un file con questa estensione viene considerato essere del bytecode Perl generato da B::Bytecode. Se questo file viene trovato e il suo istante di modifica è più recente di un coincidente e non compilato file ".pm", verrà caricato al posto del file non compilato che finisce con una estensione ".pm".
Potete anche inserire degli hook (**) nel servizio di importazione, inserendo del codice Perl direttamente nell'array @INC. Ci sono tre tipi di hook: riferimenti a subroutine, riferimenti ad array e oggetti blessed (***).
I riferimenti a subroutine sono il caso più semplice. Quando il sistema di inclusione esamina @INC ed incontra una subroutine, essa viene chiamata con due parametri: il primo è un riferimento a se stessa, il secondo è il nome del file da includere (es. "Pippo/Pluto.pm"). La subroutine deve restituire undef oppure un filehandle, dal quale verrà letto il file da includere. Se viene restituito undef, require esaminerà i rimanenti elementi di @INC.
Se l'hook è un riferimento ad un array, il primo elemento di tale array deve essere un riferimento ad una subroutine. Questa subroutine è chiamata come sopra, ma il primo parametro è il riferimento all'array. Ciò permette di passare alcuni argomenti alla subroutine, indirettamente.
In altre parole, potete scrivere:
push @INC, \&mia_sub;
sub my_sub {
my ($refcodice, $nomefile) = @_; # $refcodice e` \&my_sub
...
}
oppure:
push @INC, [ \&mia_sub, $x, $y, ... ];
sub mia_sub {
my ($refarray, $nomefile) = @_;
# Recupera $x, $y, ...
my @parametri = @$refarray[1..$#$refarray];
...
}
Se l'hook è un oggetto, deve fornire un metodo INC che verrà chiamato come sopra, ed a cui verrà passato l'oggetto stesso come primo parametro. (Va notato che dovete indicare il nome completo della sub, poiché esso viene sempre forzato dentro il package main). Di seguito è riportato un tipico schema di codice:
# In Pippo.pm
package Pluto;
sub new { ... }
sub Pluto::INC {
my ($self, $nomefile) = @_;
...
}
# Nel programma principale
push @INC, new Pluto(...);
Va notato che a questi hook è anche permesso impostare la voce in %INC corrispondente ai file che essi hanno caricato. Consultate "%INC" in perlvar.
Per un servizio di importazione ancora più potente, consultate "use" e perlmod.
(*) Letteralmente parola nuda, indica una parola che potrebbe essere la chiamata di una funzione (ma non ha né & all'inizio né () alla fine) ed è per questo ambigua per perl a tempo di compilazione. In assenza di use strict 'subs' (che genera errore) viene trattata come se fosse inclusa tra virgolette. [NdT]
(**) letteralmente aggancio, questo termine indica la procedura di codificare un programma che permetta all'utente di espanderlo. Ad esempio il funzionamento dei plugin di <programma con plugin> è permesso grazie a degli hook. [NdT]
(***) letteralmente santificato, consacrato, si intende di un oggetto che è stato legato al nome di un package. Si veda la funzione bless. [NdT]
Generalmente utilizzata in un blocco continue alla fine di un ciclo per pulire variabili e azzerare le ricerche ?? in modo che funzionino di nuovo. L'espressione viene interpretata come una lista di singoli caratteri (i trattini sono ammessi per creare degli intervalli). Tutte le variabili e gli array che cominciano per una di tali lettere vengono ripristinati al loro stato precedente. Se l'espressione viene omessa, solo le ricerche di una singola corrispondenza (?pattern?) vengono azzerate per funzionare di nuovo. Vengono pulite solo le variabili o le ricerche nel package corrente. Restituisce sempre 1. Esempi:
reset 'X'; # pulisce tutte le variabili X
reset 'a-z'; # pulisce tutte le variabili minuscole
reset; # azzera solo le ricerche ?pattern?
Chiamare un reset di "A-Z" non è consigliabile poiché svuoterebbe, fra le altre cose, gli array @ARGV e @INC e l'hash %ENV. Vengono reinizializzate solo le variabili di package, le variabili lessicali non vengono toccate, ma in ogni caso queste si azzerano da sole all'uscita dallo scope, quindi probabilmente la cosa migliore è utilizzare variabili lessicali. Si veda "my".
Ritorna da una subroutine, da un eval o da un do FILE con il valore dato in ESPR. La valutazione di ESPR può essere fatta in contesto scalare, lista, o vuoto, a seconda di come viene utilizzato il valore restituito, e il contesto può variare da una invocazione ad un'altra (si veda wantarray). Se ESPR viene omessa, restituisce una lista vuota in contesto lista, il valore indefinito in contesto scalare, e (ovviamente) nulla in contesto vuoto.
(Va notato che in assenza di un return esplicito, una subroutine, eval o do FILE restituiscono automaticamente il valore dell'ultima espressione valutata).
In un contesto di lista, restituisce una lista di valori contenente gli elementi di LISTA in ordine inverso. In un contesto scalare, concatena gli elementi di LISTA e restituisce un valore di stringa con tutti i caratteri in ordine inverso.
print reverse <>; # inversione della lista, l'ultima linea diventa la prima
undef $/; # per maggiore efficienza di <>
print scalar reverse <>; # inversione dei caratteri, l'ultima linea diventa la amirp
Utilizzata senza argomenti in un contesto scalare, reverse() inverte $_.
Questo operatore è utile anche per invertire un hash, nonostante ci siano alcuni aspetti di cui tenere conto. Se un valore dell'hash originale è doppio, solo uno di essi può diventare una chiave nell'hash invertito. Inoltre, questa operazione deve analizzare un hash e costruirne uno nuovo, e la cosa potrebbe richiedere del tempo su un hash grande, ad esempio un file DBM.
%per_nome = reverse %per_indirizzo; # Inverte l'hash
Imposta la posizione corrente di DIRHANDLE all'inizio della directory per la funzione readdir.
Funziona come index(), solo che restituisce la posizione dell'ultima occorrenza di SOTTOSTR in STR. Se viene specificata una POSIZIONE, restituisce l'ultima occorrenza che inizia a oppure entro quella posizione.
Cancella la directory indicata da NOMEFILE, se tale directory è vuota. In caso di successo restituisce vero, altrimenti restituisce falso ed imposta $! (errno). Se NOMEFILE viene omesso, viene usato $_.
L'operatore di sostituzione. Consultate perlop.
Forza ESPR ad essere interpretata in un contesto scalare e restituisce il valore di ESPR.
@conteggi = ( scalar @a, scalar @b, scalar @c );
Non c'è un operatore equivalente per forzare un espressione ad essere interpolata in un contesto di lista perché in pratica questo non è mai necessario. Comunque, se volete davvero farlo, potreste usare il costrutto @{[ (una qualche espressione) ]}, ma di solito è sufficiente un semplice (una qualche espressione)
Dato che scalar è un operatore unario, se accidentalmente per ESPR utilizzate una lista con parentesi, questo ha un comportamento analogo ad una espressione virgola scalare che valuta tutto in un contesto vuoto meno l'ultimo elemento e che restituisce l'elemento finale valutato in un contesto scalare. Spesso questo è quello di cui si ha bisogno.
La seguente singola istruzione:
print uc(scalar(&pippo,$pluto)),$paperino;
è l'equivalente virtuoso di queste due:
&pippo;
print(uc($pluto),$paperino);
Consultate perlop per maggiori dettagli sugli operatori unari e sull'operatore virgola.
Imposta la posizione nel FILEHANDLE, proprio come la funzione fseek della libreria stdio. FILEHANDLE può essere un'espressione il cui valore restituisce il nome del filehandle. I valori per DA_DOVE sono: 0 per impostare in bytes la nuova posizione a POSIZIONE, 1 per impostarla alla posizione corrente più POSIZIONE, e 2 per impostarla a EOF (fine del file) più POSIZIONE (generalmente negativa). Per DA_DOVE si possono utilizzare le costanti SEEK_SET, SEEK_CUR e SEEK_END (inizio del file, posizione corrente, fine del file) definite nel modulo Fcntl. Restituisce 1 se l'operazione è stata eseguita correttamente, 0 altrimenti.
Da notare l'espressione in bytes: anche se il file è stato impostato per operare su caratteri (ad esempio utilizzando lo strato aperto :utf8), tell() restituisce uno scostamento in bytes, non in numero di caratteri (poiché un'implementazione in tal senso renderebbe seek() e tell() piuttosto lente).
Per posizionarsi nel file per eseguire sysread o syswrite, non utilizzate seek, l'utilizzo del buffering rende il suo effetto sul file imprevedibile e non portabile. Utilizzate invece sysseek.
A causa delle regole ferree dell'ANSI C, su alcuni sistemi è necessario un seek ogni volta che si passa da operazioni di lettura a operazioni di scrittura. Fra le altre cose, questo potrebbe avere l'effetto di chiamare la funzione stdio clearerr(3). Un DA_DOVE di 1 (SEEK_CUR) può essere utile per non muovere la posizione nel file:
seek(TEST,0,1);
Questo può anche essere utile per applicazioni che simulino il comportamento di tail -f. Una volta raggiunto EOF in lettura del file, potrebbe essere necessario un seek() per rimettere le cose a posto. Il seek non cambia la posizione corrente, ma fa in modo che la condizione di fine del file venga reimpostata, in modo che al prossimo <FILE> Perl tenti nuovamente di leggere qualcosa. O almeno così dovrebbe essere.
Se questo non dovesse funzionare (alcune implementazioni dell'IO sono particolarmente bizzose), ci potrebbe essere bisogno di qualcosa di simile a:
for (;;) {
for ($poscorrente = tell(FILE); $_ = <FILE>;
$poscorrente = tell(FILE)) {
# cerca qualcosa e scrivilo in qualche file
}
sleep($un_poco);
seek(FILE, $poscorrente, 0);
}
Imposta su DIRHANDLE la posizione corrente per la routine readdir. POS dev'essere un valore restituito da telldir. Riguardo a possibili compattazioni di directory, seekdir ha gli stessi avvertimenti della corrispondente routine della libreria di sistema.
Restituisce il filehandle correntemente selezionato. Nel caso FILEHANDLE venga specificato, imposta il filehandle corrente per l'output. Ciò ha due effetti: anzitutto, un write o un print senza filehandle verrà indirizzato a questo FILEHANDLE. In secondo luogo, i riferimenti alle variabili relative all'output si riferiranno a questo canale di output. Ad esempio, se dovete impostare il formato di inizio modulo per più di un canale di output, potreste fare come di seguito indicato:
select(RAPPORTO1);
$^ = 'rapporto1_top';
select(RAPPORTO2);
$^ = 'rapporto2_top';
FILEHANDLE può essere un'espressione il cui valore fornisce il nome del reale filehandle. Dunque:
$vecchiofh = select(STDERR); $| = 1; select($vecchiofh);
Alcuni programmatori magari preferiscono pensare ai filehandle come ad oggetti con metodi, preferendo scrivere l'ultimo esempio come:
use IO::Handle;
STDERR->autoflush(1);
Questa funzione invoca la chiamata di sistema select(2) con le maschere di bit specificate, che possono essere costruite utilizzando fileno e vec, su questa falsariga:
$rin = $win = $ein = '';
vec($rin,fileno(STDIN),1) = 1;
vec($win,fileno(STDOUT),1) = 1;
$ein = $rin | $win;
Se desiderate chiamare select su più filehandle, potreste voler scrivere una subroutine:
sub fhbits {
my(@fhlist) = split(' ',$_[0]);
my($bits);
for (@fhlist) {
vec($bits,fileno($_),1) = 1;
}
$bits;
}
$rin = fhbits('STDIN TTY SOCK');
L'idioma consueto è:
($ntrovati,$temporimasto) =
select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
oppure si può bloccare fino a che qualcosa non diventa pronto
$ntrovati = select($rout=$rin, $wout=$win, $eout=$ein, undef);
La maggior parte dei sistemi non si preoccupano di restituire qualcosa di utile in $temporimasto, quindi una chiamata a select() in contesto scalare restituisce semplicemente $ntrovati.
Qualsiasi delle bitmask può avere valore undef (non definito). Il timeout, qualora specificato, è in secondi, che possono anche essere una frazione. Nota: non tutte le implementazioni sono in grado di restituire il $temporimasto. Se non lo sono, restituiscono sempre un $temporimasto uguale al $timeout fornito.
Potete creare uno sleep di 250 millisecondi in questo modo:
select(undef, undef, undef, 0.25);
Va notato che il fatto che select venga riavviata dopo un segnale (ad esempio, SIGALRM) dipende dall'implementazione. Si veda anche perlport per delle note sulla portabilità di select.
In caso di errore, select si comporta come la chiamata di sistema select(2): essa restituisce -1 ed imposta $!.
Nota: su alcuni Unix, la chiamata di sistema select(2) potrebbe riferire come "pronto per la lettura" un descrittore di file di un socket, quando in effetti non è disponibile alcun dato, con conseguente bloccaggio a causa di una successiva lettura. Può essere evitato utilizzando sempre il flag O_NONBLOCK sul socket. Si vedano select(2) and fcntl(2) per ulteriori dettagli.
ATTENZIONE: Non si dovrebbe tentare di mescolare l'I/O con buffer (come read o <FH>) con select, tranne per come viene permesso da POSIX, ed anche in quel caso solo su sistemi POSIX. In quel caso dovete usare sysread.
Chiama la funzione semctl del System V IPC. Probabilmente dovrete prima dichiarare
use IPC::SysV;
per ottenere le definizioni di costante corrette. Se CMD è IPC_STAT o GETALL, allora ARG deve essere una variabile, che conserverà la struttura semid_ds restituita o l'array di valori del semaforo. Restituisce dei valori come fa ioctl: il valore indefinito in caso di errore, "0 ma vero" in caso di zero o altrimenti l'effettivo valore restituito. ARG deve essere un vettore di interi short nativi, che possono essere creati utilizzando pack("s!",(0)x$nsem). Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::Semaphore.
Chiama la funzione semget del System V IPC. Restituisce l'id del semaforo, o il valore indefinito se si verifica un errore. Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::SysV::Semaphore.
Chiama la funzione semop del System V IPC, per compiere operazioni con i semafori quali segnalazione ed attesa. STRINGAOPZ dev'essere un array compattato di strutture semop. Ciascuna struttura semop può essere generata utilizzando pack("s!3", $numsem, $opsem, $flagsem). La lunghezza di STRINGAOPZ implica il numero di operazioni sui semafori. Restituisce vero in caso di successo, oppure falso nel caso si verifichi un errore. Ad esempio, il seguente codice attende sul semaforo $numsem dell'id di semaforo $idsem:
$opsem = pack("s!3", $numsem, -1, 0);
die "Problema con il semaforo: $!\n" unless semop($idsem, $opsem);
Per inviare un segnale al semaforo, sostituite -1 con 1. Consultate anche la documentazione di "SysV IPC" in perlipc, IPC::SysV e IPC::SysV::Semaphore.
Invia un messaggio ad un socket. Tenta di inviare lo scalare MSG al filehandle SOCKET. Accetta gli stessi flag dell'omonima chiamata di sistema. Su socket non connessi, dovete specificare una destinazione DEST, nel qual caso viene effettuata una sendto. Restituisce il numero di caratteri inviati, oppure il valore indefinito in caso di errore. La chiamata di sistema C sendmsg(2) non è attualmente implementata. Consultate "UDP: Message Passing" in perlipc ["UDP: Passaggio di messaggi", NdT] per degli esempi.
Notate i caratteri: a seconda dello stato del socket, possono essere inviati byte (8-bit) o caratteri. Di default tutti i socket operano su byte, ma se ad esempio il socket è stato alterato utilizzando binmode() per operare con il layer di I/O :utf8 (si veda "open", o la direttiva open, open), le operazioni di I/O opereranno su caratteri, non su byte. In maniera analoga per la direttiva :encoding: in quel caso può essere inviato pressoché qualsiasi carattere.
Imposta il gruppo corrente del processo per il PID specificato, 0 per il processo corrente. Genera un errore bloccante se è usata su una macchina che non implementa la chiamata POSIX setpgid(2) o la chiamata BSD setpgrp(2). Se gli argomenti vengono messi, li imposta di default a 0,0. Va notato che la versione BSD 4.2 di setpgrp non accetta alcun argomento, dunque solamente setpgrp(0,0)> è portabile. Consultate anche POSIX::setsid().
Imposta la priorità corrente per un processo, un gruppo di processi, o un utente. (Consultate setpriority(2)). Genera un errore bloccante se utilizzata su una macchina che non implementa setpriority(2).
Imposta l'opzione richiesta del socket. Restituisce il valore indefinito se si verifica un errore. Per LIVELLO e NOMEOPZ usate le costanti intere fornite dal modulo Socket. Anche i valori per LIVELLO possono essere ottenuti da getprotobyname. VALOREOPZ potrebbe essere o una stringa compattata oppure un intero. Un intero VALOREOPZ è un modo stenografico per dire pack("i", VALOREOPZ).
Un esempio che disabilita l'algoritmo di Nagle per un socket:
use Socket qw(IPPROTO_TCP TCP_NODELAY);
setsockopt($socket, IPPROTO_TCP, TCP_NODELAY, 1);
Rimuove il primo elemento dell'array e lo restituisce, accorciando l'array di una unità e scalando tutti gli elementi di un posto verso il basso. Se non ci sono elementi nell'array, restituisce il valore indefinito. Se ARRAY viene omesso, l'operazione viene effettuata sull'array @_ se ci si trova all'interno dello scope lessicale di subroutine e formati, e dell'array @ARGV se ci si trova all'interno di scope di file oppure all'interno di scope lessicali stabiliti dai costrutti eval '', BEGIN {}, INIT {}, CHECK {} e END {}.
Consultate anche unshift, push e pop. shift e unshift fanno all'estremità sinistra di un array ciò che pop and push fanno alla parte destra.
Chiama la funzione shmctl del System V IPC. Probabilmente prima dovrete dichiarare
use IPC::SysV;
per ottenere le definizioni di costante corrette. Se CMD è IPC_STAT, allora ARG deve essere una variabile che conserverà la struttura shmid_ds restituita. Restituisce dei valori come fa ioctl: il valore indefinito in caso di errore, "0 ma vero" in caso di zero o altrimenti l'effettivo valore restituito. Consultate anche "SysV IPC" in perlipc e la documentazione di IPC::SysV.
Chiama la funzione shmget del System V IPC. Restituisce l'id del segmento di memoria condivisa, o un valore indefinito se si verifica un errore. Consultate anche la documentazione di "SysV IPC" in perlipc e IPC::SysV.
Legge o scrive il segmento di memoria condivisa System V indicato da ID, partendo dalla posizione POS per la dimensione DIMENSIONE, connettendosi ad essa, copiando su o da essa, e disconnettendosi. Durante la lettura, VAR deve essere una variabile che conterrà i dati letti. Durante la scrittura, se STRINGA è troppo lunga, saranno usati solo un numero di byte pari a DIMENSIONE; se STRINGA è troppo corta, dei null verranno scritti per riempire un numero di byte pari a DIMENSIONE. Restituisce vero se ha successo oppure falso se si è verificato un errore. shmread() effettua un taint sulla variabile. Consultate anche "SysV IPC" in perlipc, la documentazione di IPC::SysV e il modulo IPC::Shareable su CPAN.
Chiude la connessione ad un socket nella maniera indicata da COME, che ha lo stesso significato dell'omonima chiamata di sistema.
shutdown(SOCKET, 0); # abbiamo finito di leggere dati
shutdown(SOCKET, 1); # abbiamo finito di scrivere dati
shutdown(SOCKET, 2); # abbiamo finito di usare il socket
Questo è utile nella gestione dei socket quando si vuole far sapere all'altro lato della connessione che si ha finito di scrivere ma non di leggere, o viceversa. È anche una forma di chiusura più drastica di close perché rende invalido il descrittore di file in tutte le copie del processo ottenute tramite fork.
Restituisce il seno di ESPR (espresso in radianti). Se ESPR viene omessa, restituisce il seno di $_.
Per l'operazione di seno inverso, potete usare la funzione Math::Trig::asin, oppure usare questa relazione:
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
Fa sì che lo script si fermi per ESPR secondi, o per sempre se non viene specificata ESPR. Può essere interrotta se il processo riceve un segnale quale SIGALARM. La funzione restituisce il numero di secondi realmente impiegati nella pausa. Verosimilmente non potete mischiare chiamate a alarm e sleep, poiché sleep è spesso implementata utilizzando alarm.
Su alcuni sistemi più vecchi, la pausa potrebbe durare un intero secondo meno di quanto richiesto, a seconda della maniera con cui vengono contati i secondi. La maggior parte dei moderni sistemi si ferma per il giusto numero di secondi. Può sembrare che la pausa sia più lunga, poiché in un ambiente multitasking affollato, il vostro processo potrebbe non iniziare subito la pausa.
Per intervalli di maggior precisione di un secondo, potete usare l'interfaccia syscall del Perl per accedere a setitimer(2), se il vostro sistema la supporta; altrimenti guardate "select" più in alto. Anche il modulo Time::HiRes (da CPAN, e nella distribuzione standard a partire da Perl 5.8) può esservi di aiuto.
Consultate anche la funzione pause del modulo POSIX.
Apre un socket del tipo specificato e lo collega al filehandle SOCKET. DOMINIO, TIPO e PROTOCOLLO sono specificati come per la chiamata di sistema dello stesso nome. Dovreste prima utilizzare use Socket per ottenere l'importazione delle opportune definizioni. Consultate gli esempi in "Sockets: Client/Server Communication" in perlipc ["Socket: Comunicazione Client/Server", NdT].
Sui sistemi che supportano sui file un flag close-on-exec [chiudi-su-esecuzione, NdT], il flag sarà impostato per il descrittore di file appena aperto, come determinato dal valore di $^F. Consultate "$^F" in perlvar.
Crea una coppia di socket senza nome, nello specificato dominio, del tipo specificato. DOMINIO, TIPO e PROTOCOLLO sono specificati come per la chiamata di sistema dello stesso nome. Se non implementato, produce un errore bloccante. Restituisce vero se ha successo.
Sui sistemi che supportano sui file un flag close-on-exec [chiudi-su-esecuzione, NdT], il flag sarà impostato per il descrittore di file appena aperto, come determinato dal valore di $^F. Consultate "$^F" in perlvar.
Alcuni sistemi definiscono pipe in termini di socketpair, nel quale una chiamata a pipe(Rdr, Wtr) è essenzialmente:
use Socket;
socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
shutdown(Rdr, 1); # non piu` scritture per chi legge
shutdown(Wtr, 0); # non piu` letture per chi scrive
Consultate perlipc per un esempio sull'utilizzo di socketpair. Perl 5.8 e successivi emuleranno socketpair usando i socket IP su localhost nel caso che il vostro sistema implementi i socket ma non socketpair.
In un contesto di lista, ordina la LISTA e restituisce il valore della lista ordinata. In un contesto scalare il comportamento di sort() è indefinito.
Se NOMESUB o BLOCCO vengono omessi, ordina secondo il confronto standard tra stringhe. Se NOMESUB viene specificato, esso fornisce il nome di una subroutine che restituisce un intero minore, uguale o maggiore di 0 a seconda di come gli elementi della lista devono essere ordinati. (Gli operatori <=> e cmp sono estremamente utili in tali routine). NOMESUB può essere il nome di una variabile scalare (senza indici di array o chiavi di hash), nel qual caso il valore fornisce il nome (o un riferimento) della subroutine che si deve in effetti usare. Al posto di NOMESUB si può fornire un BLOCCO in qualità di subroutine anonima, interna.
Se il prototipo della subroutine è ($$), gli elementi da confrontare sono passati per riferimento in @_, come accade per una normale subroutine. Ciò è più lento rispetto ad una subroutine senza prototipo, dove gli elementi da confrontare sono passati alla subroutine nelle variabili package globali $a e $b (guardate l'esempio sottostante). Va notato che in quest'ultimo caso è tipicamente controproducente dichiarare $a e $b come lessicali.
In entrambi i casi la subroutine non può essere ricorsiva. I valori da confrontare sono sempre passati per riferimento, quindi non dovrebbero essere modificati.
Inoltre, non potete uscire dal blocco o dalla subroutine di ordinamento usando uno degli operatori di controllo del ciclo descritti in perlsyn o con goto.
Quando use locale è attivo, sort LISTA ordina la lista secondo il riscontro del "locale" corrente. Consultate perllocale.
sort() restituisce gli alias alla lista originaria, così come una variabile indice del ciclo for restituisce degli alias agli elementi della lista.
Cioè, modificare un elemento di una lista restituita da sort() (per esempio, in un foreach, map o grep) modifica proprio l'elemento della lista originare
Perl 5.6 e le versioni precedenti usavano l'algoritmo quicksort per implementare l'ordinamento. Quell'algoritmo non era stabile, e avrebbe potuto avere un comportamento quadratico. (Un ordinamento stabile preserva l'ordine degli elementi in input che risultano uguali. Benché il tempo d'esecuzione di quicksort sia O(NlogN) in media su tutti gli array di lunghezza N, il tempo può essere O(N**2), ovvero comportarsi quadraticamente, per alcuni input). Nella versione 5.7, l'implementazione di quicksort è stata rimpiazzata da un algoritmo mergesort stabile il cui comportamento nel caso pessimo è O(NlogN). Ma i benchmark indicavano che per alcuni input, su alcune piattaforme, il quicksort originale andava più veloce. La versione 5.8 ha una direttiva sort che consente un limitato controllo su sort. Il suo blando controllo dell'algoritmo sottostante potrebbe scomparire nelle prossime versioni di Perl, ma l'abilità di caratterizzare l'input e l'output in modi indipendenti dall'implementazione probabilmente non lo farà. Consultate sort.
Esempi:
# ordinamento lessicale
@articoli = sort @file;
# stessa cosa, ma con una routine esplicita di ordinamento
@articoli = sort {$a cmp $b} @file;
# ora senza tener conto di maiuscole e minuscole
@articoli = sort {uc($a) cmp uc($b)} @file;
# stessa cosa in ordine inverso
@articoli = sort {$b cmp $a} @file;
# ordinamento numerico ascendente
@articoli = sort {$a <=> $b} @file;
# ordinamento numerico discendente
@articoli = sort {$b <=> $a} @file;
# ordina l'hash %eta per valore anziche' per chiave
# usando una funzione interna
@prima_gli_anziani = sort { $eta{$b} <=> $eta{$a} } keys %eta;
# ordina usando il nome della subroutine esplicito
sub pereta {
$eta{$a} <=> $eta{$b}; # si assume siano chiavi numeriche
}
@classe_ordinata = sort pereta @classe;
sub alcontrario { $b cmp $a }
@harry = qw(cane gatto x Caino Abele);
@george = qw(andato inseguito yz Punito Accettato);
print sort @harry;
# stampa AbelCaincatdogx AbeleCainocanegattox
print sort alcontrario @harry;
# stampa xdogcatCainAbel xgattocaneCainoAbele
print sort @george, 'to', @harry;
# stampa AbeleAccettatoCainoPunitoandatocanegattoinseguitotoxyz
# ordinamento inefficiente ottenuto per confronto
# numerico discendente del primo numero dopo
# il primo segno =, o altrimenti per confronto
# di tutto il record, senza tener conto di
# maiuscole e minuscole
@nuovo = sort {
($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
||
uc($a) cmp uc($b)
} @vecchio;
# stessa cosa, ma in maniera molto piu` efficiente;
# costruiamo indici ausiliari, per aumentare la
# velocita`
@numeri = @inmaiuscolo = ();
for (@vecchio) {
push @numeri, /=(\d+)/;
push @inmaiuscolo, uc($_);
}
@nuovo = @vecchio[ sort {
$numeri[$b] <=> $numeri[$a]
||
$caps[$a] cmp $caps[$b]
} 0..$vecchio
];
# stessa cosa, ma senza variabili temporanee
@nuovo = map { $_->[0] }
sort { $b->[1] <=> $a->[1]
||
$a->[2] cmp $b->[2]
} map { [$_, /=(\d+)/, uc($_)] } @vecchio;
# l'uso di un prototipo consente di usare, con sort,
# qualunque subroutine di confronto (comprese le
# subroutine definite in altri package)
package altro;
sub alcontrario ($$) { $_[1] cmp $_[0]; } # $a e $b, qui, non sono impostate
package main;
@nuovo = sort altro::alcontrario @vecchio;
# stabilita` garantita, qualunque sia l'algoritmo
use sort 'stable';
@nuovo = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @vecchio;
# forza l'uso di mergesort (non portabile al di
# fuori della versione 5.8 di Perl)
use sort '_mergesort'; # notate il _ che ne
# scoraggia l'uso
@nuovo = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @vecchio;
Se state usando strict, non dovete dichiarare $a e $b come lessicali. Sono variabili globali del package. Questo significa che se siete nel package main e scrivete
@articoli = sort { $b <=> $a } @file;
allora $a e $b sono $main::a e $main::b (o $::a e $::b), ma se siete nel package PackagePippo è lo stesso che scrivere
@articoli = sort { $PackagePippo::b <=> $PackagePippo::a } @file;
Si richiede che la funzione di confronto si comporti in modo consistente. Se restituisce risultati inconsistenti (dicendo a volte che $x[1] è più piccolo di $x[2] e a volte il contrario, per esempio) i risultati non sono ben definiti.
Poiché <=> restituisce undef quando uno degli operandi è NaN (not-a-number) [non-un-numero, NdT], e poiché sort genererà un errore bloccante a meno che il risultato del confronto sia definito, quando effettuate un ordinamento con una funzione di confronto come $a <=> $b, state attenti alle liste che potrebbero contenere NaN. Il seguente esempio sfrutta il fatto che NaN != NaN, per eliminare ogni NaN dall'input.
@risultati = sort { $a <=> $b } grep { $_ == $_ } @input;
Rimuove da un array gli elementi indicati da OFFSET e LUNGHEZZA, e li sostituisce con gli elementi di LISTA, se specificata. In contesto di lista, restituisce gli elementi rimossi dall'array. In contesto scalare, restituisce l'ultimo elemento rimosso, o undef se nessun elemento viene rimosso. L'array si espande o rimpicciolisce come necessario. Se SCOSTAMENTO è negativo, allora esso viene considerato a partire dalla fine dell'array. Se LUNGHEZZA viene omesso, rimuove tutto da SCOSTAMENTO in poi. Se LUNGHEZZA è negativo, rimuove tutti gli elementi da SCOSTAMENTO in poi, tranne -LUNGHEZZA elementi alla fine dell'array. Se sia SCOSTAMENTO che LUNGHEZZA vengono omessi, rimuove tutto. Se SCOSTAMENTO è oltre la fine dell'array, perl emette un avvertimento, e unisce alla fine dell'array.
Si hanno le seguenti equivalenze (assumendo $[ == 0 e $#a >= $i):
push(@a,$x,$y) splice(@a,@a,0,$x,$y)
pop(@a) splice(@a,-1)
shift(@a) splice(@a,0,1)
unshift(@a,$x,$y) splice(@a,0,0,$x,$y)
$a[$x] = $y splice(@a,$x,1,$y)
Ad esempio, assumendo che le lunghezze degli array siano passate prima degli array:
sub aeq { # confronta due liste
my(@a) = splice(@_,0,shift);
my(@b) = splice(@_,0,shift);
return 0 unless @a == @b; # stessa lunghezza?
while (@a) {
return 0 if pop(@a) ne pop(@b);
}
return 1;
}
if (&aeq($lungh,@pippo[1..$lungh],0+@pluto,@pluto)) { ... }