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.
- Funzioni per SCALARI o stringhe
-
chomp , chop , chr , crypt , hex , index , lc , lcfirst ,
length , oct , ord , pack , q/STRINGA/ , qq/STRINGA/ , reverse ,
rindex , sprintf , substr , tr/// , uc , ucfirst , y///
- Espressioni regolari e ricerca di pattern
-
m// , pos , quotemeta , s/// , split , study , qr//
- Funzioni numeriche
-
abs , atan2 , cos , exp , hex , int , log , oct , rand ,
sin , sqrt , srand
- Funzioni per @ARRAY effettivi
-
pop , push , shift , splice , unshift
- Funzioni per liste di dati
-
grep , join , map , qw/STRINGA/ , reverse , sort , unpack
- Funzioni per %HASH effettivi
-
delete , each , exists , keys , values
- Funzioni di input e output
-
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
- Funzioni per dati a lunghezza fissa o record
-
pack , read , syscall , sysread , syswrite , unpack , vec
- Funzioni per filehandle, file o directory
-
-X , chdir , chmod , chown , chroot , fcntl , glob ,
ioctl , link , lstat , mkdir , open , opendir ,
readlink , rename , rmdir , stat , symlink , sysopen ,
umask , unlink , utime
- Parole chiave relative al controllo di flusso del vostro programma Perl
-
caller , continue , die , do , dump , eval , exit ,
goto , last , next , redo , return , sub , wantarray
- Parole chiave relative alla visibilità delle variabili (scoping)
-
caller , import , local , my , our , package , use
- Funzioni varie
-
defined , dump , eval , formline , local , my , our , reset ,
scalar , undef , wantarray
- Funzioni per processi e gruppi di processi
-
alarm , exec , fork , getpgrp , getppid , getpriority , kill ,
pipe , qx/STRINGA/ , setpgrp , setpriority , sleep , system ,
times , wait , waitpid
- Parole chiave relative ai moduli perl
-
do , import , no , package , require , use
- Parole chiave relative alle classi e al campo dell'orientamento agli oggetti
-
bless , dbmclose , dbmopen , package , ref , tie , tied ,
untie , use
- Funzioni di basso livello per i socket
-
accept , bind , connect , getpeername , getsockname ,
getsockopt , listen , recv , send , setsockopt , shutdown ,
socket , socketpair
- Funzioni di comunicazione tra processi di System V
-
msgctl , msgget , msgrcv , msgsnd , semctl , semget , semop ,
shmctl , shmget , shmread , shmwrite
- Recupero delle informazioni dell'utente e del gruppo
-
endgrent , endhostent , endnetent , endpwent , getgrent ,
getgrgid , getgrnam , getlogin , getpwent , getpwnam ,
getpwuid , setgrent , setpwent
- Recupero delle informazioni di rete
-
endprotoent , endservent , gethostbyaddr , gethostbyname ,
gethostent , getnetbyaddr , getnetbyname , getnetent ,
getprotobyname , getprotobynumber , getprotoent ,
getservbyname , getservbyport , getservent , sethostent ,
setnetent , setprotoent , setservent
- Funzioni relative al tempo
-
gmtime , localtime , time , times
- Nuove funzioni in perl5
-
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.
- Funzioni obsolete in perl5
-
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.
- -X FILEHANDLE
-
- -X EXPR
-
- -X
-
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 _;
- abs VALORE
-
- abs
-
Restituisce il valore assoluto del suo argomento.
Se VALORE viene omesso,
abs() usa $_ .
- accept NUOVOSOCKET,GENERICOSOCKET
-
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
perlipc/``Sockets: Client/Server Communication'' [``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 perlvar/$^F.
- alarm SECONDI
-
- alarm
-
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 perlipc/``Signals'' [``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.
- atan2 Y,X
-
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.
- bind SOCKET,NOME
-
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
perlipc/``Sockets: Client/Server Communication'' [``Socket: Comunicazione Client/Server'', NdT]..
- binmode FILEHANDLE, STRATO
-
- binmode FILEHANDLE
-
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.
- bless RIF,NOMECLASSE
-
- bless RIF
-
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 perlmod/``Perl Modules'' [``Moduli Perl'', NdT].
- caller ESPR
-
- caller
-
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.
- chdir ESPR
-
- chdir FILEHANDLE
-
- chdir DIRHANDLE
-
- chdir
-
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.
- chmod LISTA
-
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.
- chomp VARIABILE
-
- chomp( LISTA )
-
- chomp
-
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) .
- chop VARIABILE
-
- chop( LISTA )
-
- chop
-
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.
- chown LISTA
-
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);
- chr NUMERO
-
- chr
-
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.
- chroot NOMEFILE
-
- chroot
-
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 $_ .
- close FILEHANDLE
-
- close
-
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.
- closedir DIRHANDLE
-
Chiude una directory aperta da
opendir e restituisce l'esito di
quella chiamata di sistema.
- connect SOCKET,NOME
-
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 perlipc/``Sockets: Client/Server Communication''
[``Socket: Comunicazione Client/Server'', NdT].
- continue BLOCCO
-
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.
- cos ESPR
-
- cos
-
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] ) }
- crypt TESTOINCHIARO,SEME
-
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]
- dbmclose HASH
-
[Questa funzione è stata ampiamente soppiantata dalla funzione
untie ].
Rompe il legame tra un file DBM ed un hash.
- dbmopen HASH,NOMEDB,MASCHERA
-
[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: $!";
- defined ESPR
-
- defined
-
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.
Consultate anche undef, exists, ref.
- delete ESPR
-
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];
- die LISTA
-
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 perlvar/``$/'' e 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 perlvar/$SIG{expr} 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 perlvar/$^S). Poiché
questo può causare effetti collaterali non desiderati, questo
comportamento non intuitivo potrebbe essere modificato in una versione
successiva.
- do BLOCCO
-
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.
- do
SUBROUTINE(LISTA)
-
Questa forma di chiamata a subroutine è deprecata. Consultate perlsub.
- do ESPR
-
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
perlvar/Predefined Names [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;
}
}
- dump ETICHETTA
-
- dump
-
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.
- each HASH
-
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 perlsec/``Algorithmic Complexity Attacks''
[``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 .
- eof FILEHANDLE
-
- eof ()
-
- eof
-
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 perlop/``I/O Operators''
[``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.
- eval ESPR
-
- eval BLOCCO
-
- eval
-
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.
- exec LISTA
-
- exec PROGRAMMA LISTA
-
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 perlop/```STRING`'' 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.
- exists ESPR
-
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 perlref/``Pseudo-hashes: Using an array as a hash''
[``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
- exit ESPR
-
- exit
-
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.
- exp ESPR
-
- exp
-
Restituisce e (la base naturale del logaritmo) elevato alla potenza
di ESPR. Se ESPR viene omessa, restituisce
exp($_) .
- fcntl FILEHANDLE,FUNZIONE,SCALARE
-
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";
- fileno FILEHANDLE
-
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).
- flock FILEHANDLE,OPERAZIONE
-
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().
- fork
-
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.
- format
-
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.
- formline DESCRIZIONE,LISTA
-
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.
- getc FILEHANDLE
-
- getc
-
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
perlmodlib/CPAN.
- getlogin
-
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 .
- getpeername SOCKET
-
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);
- getpgrp PID
-
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.
- getppid
-
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 .
- getpriority QUALE,CHI
-
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).
- getpwnam NOME
-
- getgrnam NOME
-
- gethostbyname NOME
-
- getnetbyname NOME
-
- getprotobyname NOME
-
- getpwuid UID
-
- getgrgid GID
-
- getservbyname NOME,PROTO
-
- gethostbyaddr INDIR,TIPOINDIR
-
- getnetbyaddr INDIR,TIPOINDIR
-
- getprotobynumber NUMERO
-
- getservbyport PORTA,PROTO
-
- getpwent
-
- getgrent
-
- gethostent
-
- getnetent
-
- getprotoent
-
- getservent
-
- setpwent
-
- setgrent
-
- sethostent RIMANI_APERTO
-
- setnetent RIMANI_APERTO
-
- setprotoent RIMANI_APERTO
-
- setservent RIMANI_APERTO
-
- endpwent
-
- endgrent
-
- endhostent
-
- endnetent
-
- endprotoent
-
- endservent
-
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 .
- getsockname SOCKET
-
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);
- getsockopt SOCKET,LIVELLO,NOMEOPZ
-
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";
- glob ESPR
-
- glob
-
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 perlop/``I/O Operators''
[``Operatori di I/O'', NdT].
A partire dalla versione 5.6.0, questo operatore è implementato
utilizzando l'estensione standard File::Glob . Consultate
the File::Glob manpage per i dettagli.
- gmtime ESPR
-
- gmtime
-
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 perlport/gmtime per ciò che concerne la portabilità.
- goto ETICHETTA
-
- goto ESPR
-
- goto &NOME
-
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.
- grep BLOCCO LISTA
-
- grep ESPR, LISTA
-
è 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.
- hex ESPR
-
- hex
-
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.
- import LISTA
-
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.
- index STR,SOTTOSTR,POSIZIONE
-
- index STR,SOTTOSTR
-
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 .
- int ESPR
-
- int
-
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().
- ioctl FILEHANDLE,FUNZIONE,SCALARE
-
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.
- join ESPR, LISTA
-
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.
- keys HASH
-
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
perlsec/``Algorithmic Complexity Attacks'' [``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 .
- kill SEGNALE, LISTA
-
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 perlipc/``Signals'' [``Segnali'', NdT] per maggiori
dettagli.
- last ETICHETTA
-
- last
-
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 .
- lc ESPR
-
- lc
-
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 $_ .
- lcfirst ESPR
-
- lcfirst
-
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 $_ .
- length ESPR
-
- length
-
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.
- link VECCHIOFILE,NUOVOFILE
-
Crea un nuovo nomefile che è un link al vecchio nomefile.
Restituisce vero in caso di successo, falso altrimenti.
- listen SOCKET,DIMENSIONECODA
-
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
perlipc/``Sockets: Client/Server Communication'' [``Socket: Comunicazione Client/Server'', NdT].
- local ESPR
-
In realtà desiderate probabilmente usare
my , poiché
local non è ciò che la maggior parte delle persone
intendono come ``locale''. Consultate perlsub/``Private Variables via my()''
[``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 perlsub/``Temporary Values via local()
[''Valori temporanei tramite local()``, NdT] per dettagli, incluse le problematiche
relative agli array ed agli hash legati [con tie , NdT].
- localtime ESPR
-
- localtime
-
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 perlport/localtime per ciò che concerne la portabilità.
- lock COSA
-
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.
- log ESPR
-
- log
-
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.
- lstat ESPR
-
- lstat
-
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 $_ .
- m//
-
L'operatore di match [corrispondenza, NdT]. Si veda perlop.
- map BLOCCO LISTA
-
- map ESPR, LISTA
-
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.
- mkdir NOMEFILE,MASK
-
- mkdir NOMEFILE
-
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.
- msgctl ID,CMD,ARG
-
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 perlipc/``SysV IPC'', IPC::SysV e IPC::Semaphore .
- msgget CHIAVE,FLAG
-
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 perlipc/``SysV IPC'', IPC::SysV e IPC::Msg .
- msgrcv ID,VAR,DIMENSIONE,TIPO,FLAG
-
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 perlipc/``SysV IPC'', IPC::SysV e
IPC::SysV::Msg .
- msgsnd ID,MSG,FLAG
-
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 .
- my ESPR
-
- my TIPO ESPR
-
- my ESPR : ATTR
-
- my TIPO ESPR : ATTR
-
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 perlsub/``Private Variables via my()''
[``Variabili private tramite my()'', NdT] per dettagli e fields, attributes e
the Attribute::Handlers manpage.
- next ETICHETTA
-
- next
-
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 .
- no Modulo VERSIONE LISTA
-
- no Modulo VERSIONE
-
- no Modulo LISTA
-
- no Modulo
-
Si veda la funzione
use , della quale no è l'opposto.
- oct ESPR
-
- oct
-
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).
- open FILEHANDLE,ESPR
-
- open FILEHANDLE,MODO,ESPR
-
- open FILEHANDLE,MODO,ESPR,LISTA
-
- open FILEHANDLE,MODO,RIFERIMENTO
-
- open FILEHANDLE
-
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 perlipc/``Using open() for IPC'' [``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 the IPC::Open2 manpage,
the IPC::Open3 manpage e perlipc/``Bidirectional Communication with Another Process''
[``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 perlipc/``Using open() for IPC'' [``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 the IPC::Open2 manpage,
the IPC::Open3 manpage e perlipc/``Bidirectional Communication''
[``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 perlipc/``Safe Pipe Opens'' [``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 perlvar/$^F.
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.
- opendir DIRHANDLE,ESPR
-
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.
- ord ESPR
-
- ord
-
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 ESPR
-
- our ESPR TIPO
-
- our ESPR : ATTRIBUTI
-
- our TIPO ESPR : ATTRIBUTI
-
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 perlsub/``Private Variables via my()''
[``Variabili private tramite my()'', NdT] per i dettagli e fields,
attributes e the Attribute::Handlers manpage.
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.
- pack TEMPLATE,LISTA
-
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:
-
Ciascuna lettera può, opzionalmente, essere seguita da un numero,
che indica il numero di ripetizioni. Con tutti i tipi tranne
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.
-
I tipi
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.
-
Allo stesso modo, i campi
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" .
-
I campi
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.
-
Il tipo
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().
-
Il template
/ 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.
-
I tipi interi
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).
-
I formati interi
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.
-
I numeri reali (float e double) sono unicamente nel formato nativo
della macchina; a causa del gran numero di formati a virgola mobile
presenti, ed a causa dell'assenza di una rappresentazione ``di rete''
standard, non è stata creato alcuno strumento per l'interscambio.
Ciò significa che i dati in virgola mobile compattati scritti su
una macchina potrebbero non essere leggibili su un'altra, persino se
entrambe usano l'aritmetica in virgola mobile IEEE (poiché il
tipo di endian delle rappresentazioni in memoria non rientra nelle
specifiche IEEE). 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).
-
Se lo schema inizia con
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.
-
Dovete occuparvi voi di eventuali allineamenti o completamenti, inserendo
ad esempio sufficienti
'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.
-
Un gruppo () è un sotto-TEMPLATE racchiuso tra parentesi. Un gruppo
può avere un conteggio di ripetizioni, sia alla fine che tramite il
template di caratteri
/ . 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.
-
Un commento in un TEMPLATE inizia con
# 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 più argomenti per
pack() di quanti ne siano
stati in realtà forniti, pack() assume un numero addizionale di
argomenti "" . 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().
- package SPAZIONOMI
-
- package
-
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 perlmod/``Packages'' per maggiori informazioni sui
package, sui moduli, e sulle classi. Consultate perlsub per
ulteriori informazioni sullo scope.
- pipe HANDLEDILETTURA,HANDLEDISCRITTURA
-
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 the IPC::Open2 manpage, the IPC::Open3 manpage e
perlipc/``Bidirectional Communication'' [``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 perlvar/$^F.
- pop ARRAY
-
- pop
-
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 .
- pos SCALARE
-
- pos
-
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.
- print FILEHANDLE LISTA
-
- print LISTA
-
- print
-
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";
- printf FILEHANDLE FORMATO,LISTA
-
- printf FORMATO,LISTA
-
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.
- prototype FUNZIONE
-
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.
- push ARRAY,LISTA
,
-
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 .
- q/STRINGA/
-
- qq/STRINGA/
-
- qr/STRINGA/
-
- qx/STRINGA/
-
- qw/STRINGA/
-
Sono delle virgolette generalizzate. Consultate perlop/``Regexp Quote-Like Operators''
[``Operatori analoghi a quelli di quoting delle espressioni regolari'', NdT].
- quotemeta ESPR
-
- quotemeta
-
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 $_ .
- rand ESPR
-
- rand
-
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).
- read FILEHANDLE,SCALARE,LUNGHEZZA,SCOSTAMENTO
-
- read FILEHANDLE,SCALARE,LUNGHEZZA
-
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.
- readdir DIRHANDLE
-
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;
- readline ESPR
-
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 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 perlop/``I/O Operators'' [``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
}
# ...
}
- readlink ESPR
-
- readlink
-
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 $_ .
- readpipe ESPR
-
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
perlop/``I/O Operators'' [``Operatori di I/O'', NdT].
- recv SOCKET,SCALARE,LUNGHEZZA,FLAG
-
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 perlipc/``UDP: Message Passing''
[``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.
- redo ETICHETTA
-
- redo
-
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 .
- ref ESPR
-
- ref
-
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.
- rename VECCHIONOME,NUOVONOME
-
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.
- require VERSIONE
-
- require ESPR
-
- require
-
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 perlvar/%INC.
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]
- reset ESPR
-
- reset
-
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.
- return ESPR
-
- return
-
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).
- reverse LISTA
-
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
- rewinddir DIRHANDLE
-
Imposta la posizione corrente di DIRHANDLE all'inizio della directory
per la funzione
readdir .
- rindex STR,SOTTOSTR,POSIZIONE
-
- rindex STR,SOTTOSTR
-
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.
- rmdir NOMEFILE
-
- rmdir
-
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 $_ .
- s///
-
L'operatore di sostituzione. Consultate perlop.
- scalar ESPR
-
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.
- seek FILEHANDLE,POSIZIONE,DA_DOVE
-
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);
}
- seekdir DIRHANDLE,POS
-
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.
- select FILEHANDLE
-
- select
-
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);
- select RBITS,WBITS,EBITS,TIMEOUT
-
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 .
- semctl ID,SEMNUM,CMD,ARG
-
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 perlipc/``SysV IPC'', IPC::SysV e IPC::Semaphore .
- semget CHIAVE,NSEM,FLAG
-
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
perlipc/``SysV IPC'',
IPC::SysV e IPC::SysV::Semaphore .
- semop CHIAVE,STRINGAOPZ
-
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 perlipc/``SysV IPC'', IPC::SysV e IPC::SysV::Semaphore .
- send SOCKET,MSG,FLAG,DEST
-
- send SOCKET,MSG,FLAG
-
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
perlipc/``UDP: Message Passing'' [``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.
- setpgrp PID,PGRP
-
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() .
- setpriority QUALE,CHI,PRIORITÀ
-
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).
- setsockopt SOCKET,LIVELLO,NOMEOPZ,VALOREOPZ
-
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);
- shift ARRAY
-
- shift
-
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.
- shmctl ID,CMD,ARG
-
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 perlipc/``SysV IPC''
e la documentazione di IPC::SysV .
- shmget CHIAVE,DIMENSIONE,FLAG
-
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 perlipc/``SysV IPC''
e
IPC::SysV .
- shmread ID,VAR,POS,DIMENSIONE
-
- shmwrite ID,STRINGA,POS,DIMENSIONE
-
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
perlipc/``SysV IPC'', la documentazione di IPC::SysV e il
modulo IPC::Shareable su CPAN.
- shutdown SOCKET,COME
-
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 .
- sin ESPR
-
- sin
-
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])) }
- sleep ESPR
-
- sleep
-
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.
- socket SOCKET,DOMINIO,TIPO,PROTOCOLLO
-
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 perlipc/``Sockets: Client/Server Communication''
[``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 perlvar/$^F.
- socketpair SOCKET1,SOCKET2,DOMINIO,TIPO,PROTOCOLLO
-
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 perlvar/$^F.
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.
- sort NOMESUB LISTA
-
- sort BLOCCO LISTA
-
- sort LISTA
-
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;
- splice ARRAY,SCOSTAMENTO,LUNGHEZZA,LISTA
-
- splice ARRAY,SCOSTAMENTO,LUNGHEZZA
-
- splice ARRAY,SCOSTAMENTO
-
- splice ARRAY
-
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)) { ... }
- split /PATTERN/,ESPR,LIMITE
-
- split /PATTERN/,ESPR
-
- split /PATTERN/
-
- split
-
Divide la stringa ESPR in una lista di stringhe e restituisce
tale lista. Di default, i campi vuoti iniziali sono
mantenuti, mentre quelli in coda vengono cancellati (se tutti i campi sono vuoti,
vengono considerati essere in coda).
In un contesto scalare, restituisce il numero di campi
trovati e mette i risultati della divisione nell'array @_ .
L'uso di split in un contesto scalare è tuttavia
deprecato, poiché sovrascrive gli argomenti
della vostra subroutine.
Se ESPR viene omessa, divide la stringa $_ . Se
anche PATTERN viene omesso, divide la stringa in base
agli spazi (dopo aver saltato ciascuno spazio presente in
testa alla stringa). Qualunque cosa soddisfi PATTERN
è trattato come un delimitatore che separa i campi.
(Va notato che il delimitatore può essere più
lungo di un carattere.)
Se LIMITE viene specificato ed è positivo,
esso rappresenta il massimo numero di campi in cui
ESPR verrà divisa, però il numero
effettivo di campi restituiti dipende da quante volte
PATTERN è soddisfatto all'interno di ESPR.
Se LIMITE non viene specificato o vale zero, allora
i campi nulli in coda vengono omessi (cosa
che i potenziali utilizzatori di pop farebbero bene
a ricordare).
Se LIMITE è negativo, allora viene trattato come
se fosse stato specificato un valore di LIMITE
arbitrariamente grande. Va notato che dividere una ESPR
che vale stringa vuota, restituisce sempre una lista
vuota, qualunque sia il LIMITE specificato.
Un pattern che corrisponde alla stringa vuota (da non
confondere con il pattern vuoto // , che è
solo un elemento dell'insieme di pattern che corrispondono
alla stringa vuota) dividerà il valore di
ESPR in caratteri separati in corrispondenza a ciascun
punto in cui il PATTERN viene soddisfatto. Ad esempio:
print join(':', split(/ */, 'ohi la'));
produce l'output 'o:h:i:l:a'.
Come caso speciale di split , utilizzare il pattern vuoto // corrisponde specificamente
al match della sola stringa vuota, e non deve essere confuso con l'uso di // per indicare ``l'ultimo pattern
soddisfatto con successo''. Così, per split , il seguente:
print join(':', split(//, 'ohi la'));
produce l'output 'o:h:i: :l:a'.
Quando ci sono dei match di ampiezza positiva all'inizio (o alla fine)
della stringa, vengono prodotti dei campi vuoti in testa (o in coda);
un match di ampiezza zero all'inizio (o alla fine) della stringa non
produce un campo vuoto. Per esempio:
print join(':', split(/(?=\w)/, 'ohi la!'));
produce l'output 'o:h:i :l:a!'.
Il parametro LIMITE può essere usato per dividere
parzialmente una linea
($login, $passwd, $rimanente) = split(/:/, $_, 3);
Quando si assegna ad una lista, se LIMITE viene omesso, oppure è
zero, Perl fornisce un valore di LIMITE che è superiore di una
unità al numero di variabili contenute nella lista, per evitare
del lavoro non necessario. Per la lista sopra, LIMITE sarebbe stato
pari a 4, di default. In applicazioni dove il tempo è un
fattore critico, è necessario non dividere in più
delle parti di cui si ha veramente bisogno.
Se il PATTERN contiene delle parentesi, vengono creati
elementi aggiuntivi nella lista, per ciascuna delle
sottostringhe corrispondenti all'interno del delimitatore.
split(/([,-])/, "1-10,20", 3);
produce il valore di lista
(1, '-', 10, ',', 20)
Se aveste in $header l'header di un normale messaggio
email Unix, potreste dividerlo in campi e rispettivi
valori in questo modo:
$header =~ s/\n\s+/ /g; # mette a posto le continuazioni delle linee
%hdrs = (UNIX_FROM => split /^(\S*?):\s*/m, $header);
Il pattern /PATTERN può essere sostituito da
una espressione per specificare pattern che variano
a tempo di esecuzione. (Per effettuare una compilazione,
a tempo di esecuzione, una volta sola, usate
/$variabile/o ).
Come caso speciale, lo specificare un PATTERN costituito da uno spazio
(' ' ) suddividerà in base agli spazi, esattamente come fa split
quando viene chiamata senza argomenti. Dunque, split(' ') può
essere utilizzata per emulare il comportamento predefinito di awk,
mentre invece split(/ /) vi restituirà tanti campi iniziali
nulli quanti sono gli spazi all'inizio della stringa.
Una split su /\s+/ è equivalente ad una split(' ') , tranne
che lo spazio bianco ad inizio stringa genera un primo campo nullo. Una
split senza argomenti in realtà, internamente, è una
split(' ', $_) .
Un PATTERN di /^/ viene trattato come se fosse /^/m poiché,
altrimenti, non sarebbe di grande utilità.
Esempio:
open(PASSWD, '/etc/passwd');
while (<PASSWD>) {
chomp;
($login, $passwd, $uid, $gid,
$gcos, $home, $shell) = split(/:/);
#...
}
Come avviene per la normale ricerca di pattern, ogni parentesi di cattura
che non viene trovata in un'operazione di split() sarà impostata ad
undef al momento della restituzione dei risultati:
@campi = split /(A)|B/, "1A2B3";
# @campi e` (1, 'A', 2, undef, 3);
- sprintf FORMATO, LISTA
-
Restituisce una stringa formattata secondo le consuete convenzioni di
printf dalla funzione
di libreria C sprintf . Guardate qui sotto per ulteriori dettagli e consultate
sprintf(3) o printf(3) sul vostro sistema operativo per una spiegazione dei
principi generali.
Per esempio:
# Stampa un numero con fino ad 8 zeri iniziali
$risultato = sprintf("%08d", $numero);
# Arrotonda un numero a 3 cifre decimali
$arrotondato = sprintf("%.3f", $numero);
Perl effettua una sua formattazione sprintf , emula la funzione C sprintf , ma non
la utilizza (eccetto per i numeri decimali, e anche in quel caso solo i modificatori
standard sono ammessi). Come risultato, ogni estensione non standard presente nella
funzione sprintf del vostro sistema operativo non è disponibile in Perl.
Diversamente da printf , sprintf non fa ciò che probabilmente ci si
aspetterebbe quando riceve un array come primo argomento. L'array viene valutato in
contesto scalare, quindi invece di utilizzare il primo elemento come formato, Perl
utilizza il numero di elementi dell'array come formato, cosa che non è quasi mai
utile.
La funzione sprintf del Perl accetta i seguenti identificatori universalmente
riconosciuti:
%% il carattere "percento"
%c il carattere con il numero indicato
%s una stringa
%d un intero con segno, in notazione decimale
%u un intero senza segno, in notazione decimale
%o un intero senza segno, in notazione ottale
%x un intero senza segno, in notazione esadecimale
%e un numero decimale, in notazione scientifica
%f un numero decimale, in notazione fissa
%g un numero decimale, in notazione %e o %f
Inoltre, Perl accetta i seguenti identificatori largamente supportati:
%X come %x, ma con lettere maiuscole
%E come %e, ma con una "E" maiuscola
%G come %g, ma con una "E" maiuscola (se applicabile)
%b un intero senza segno, in notazione binaria
%p un puntatore (restituisce l'indirizzo del valore Perl in esadecimale)
%n speciale: *memorizza* il numero di caratteri nella stringa risultante
nella prossima variabile dell'elenco dei parametri
Infine, per compatibilità all'indietro (e intendiamo ``indietro''), Perl accetta i
seguenti identificatori, superflui ma largamente supportati:
%i sinonimo per %d
%D sinonimo per %ld
%U sinonimo per %lu
%O sinonimo per %lo
%F sinonimo per %f
Va notato che il numero delle cifre nell'esponente in notazione scientifica prodotto da %e ,
%E , %g e %G per numeri con il modulo dell'esponente minore di 100 è
dipendente dal sistema: può essere tre o meno (con zero iniziali ove necessario).
In altre parole, 1.23 elevato alla novantanovesima può essere ``1.23e99'' o
``1.23e099''.
Fra il segno % e la lettera del formato, si possono specificare alcuni attributi
aggiuntivi che modificano l'interpretazione del formato. In ordine, questi sono:
- indice del parametro per il formato
-
Un indice esplicito nella lista dei parametri di formattazione, come
2$ . Per default,
sprintf formatterà il prossimo argomento non utilizzato nella lista, ma questo
attributo permette di prendere i parametri in ordine arbitrario.
Esempio:
printf '%2$d %1$d', 12, 34; # stampa "34 12"
printf '%3$d %d %1$d', 1, 2, 3; # stampa "3 1 1"
- modificatori
-
uno o più di:
spazio mette uno spazio davanti ai numeri positivi
+ mette un piu` davanti ai numeri positivi
- allinea il campo a destra
0 usa zeri invece di spazi per allineare a destra
# mette uno ``0'' davanti ad ottali, ``0x'' davanti ad esadecimali,
``0b'' davanti a binari (che non siano zero)
Per esempio:
printf '<% d>', 12; # stampa "< 12>"
printf '<%+d>', 12; # stampa "<+12>"
printf '<%6s>', 12; # stampa "< 12>"
printf '<%-6s>', 12; # stampa "<12 >"
printf '<%06s>', 12; # stampa "<000012>"
printf '<%#x>', 12; # stampa "<0xc>"
- flag ``vettore''
-
Questo flag dice a perl di interpretare la stringa che è stata fornita come
un vettore di interi, uno per ogni carattere della stringa. Perl applica il formato ad
ogni intero uno alla volta, poi unisce le stringhe risultanti con un separatore (un punto
. per default). Può essere utile per stampare i valori ordinali dei caratteri
in stringhe arbitrarie:
printf "%vd", "AB\x{100}"; # stampa "65.66.256"
printf "versione v%vd\n", $^V; # la versione del Perl
Mettete un asterisco * prima della v per modificare la stringa da utilizzare al fine di
separare i numeri:
printf "indirizzo %*vX\n", ":", $addr; # indirizzo IPv6
printf "bit %0*v8b\n", " ", $bits; # stringa di bit casuale
Si può anche specificare esplicitamente il numero dell'argomento da utilizzare
come delimitatore, utilizzando ad esempio *2$v :
printf '%*4$vX %*4$vX %*4$vX', @addr[1..3], ":"; # 3 indirizzi IPv6
- larghezza (minima)
-
Di norma, gli argomenti vengono formattati per essere larghi il numero minimo di
caratteri richiesti per mostrare il valore fornito. Potete modificare la
larghezza dando un numero, o prenderla dal prossimo argomento (con
* ) o da un
argomento specifico (con ad esempio *2$ ):
printf '<%s>', "a"; # stampa "<a>"
printf '<%6s>', "a"; # stampa "< a>"
printf '<%*s>', 6, "a"; # stampa "< a>"
printf '<%*2$s>', "a", 6; # stampa "< a>"
printf '<%2s>', "lungo"; # stampa "<lungo>" (non tronca)
Se il campo ottenuto da * è negativo, ha lo stesso effetto del modificatore
- : giustificazione a destra.
- precisione, o larghezza massima
-
Potete specificare una precisione (per argomenti numerici) o una larghezza
massima (per argomenti stringhe) utilizzando
. seguito da un numero.
Per i numeri decimali, con l'eccezione di 'g' e 'G', questo indica il numero di cifre
decimali da visualizzare (il default è 6), ad esempio:
# gli esempi sono suscettibili di variazioni in base al sistema operativo
printf '<%f>', 1; # stampa "<1.000000>"
printf '<%.1f>', 1; # stampa "<1.0>"
printf '<%.0f>', 1; # stampa "<1>"
printf '<%e>', 10; # stampa "<1.000000e+01>"
printf '<%.1e>', 10; # stampa "<1.0e+01>"
Per 'g' e 'G', questo indica il numero massimo di cifre da visualizzare, includendo sia
quelle prima che dopo il punto decimale, ad esempio:
# gli esempi sono suscettibili di variazioni in base al sistema operativo
printf '<%g>', 1; # stampa "<1>"
printf '<%.10g>', 1; # stampa "<1>"
printf '<%g>', 100; # stampa "<100>"
printf '<%.1g>', 100; # stampa "<1e+02>"
printf '<%.2g>', 100.01; # stampa "<1e+02>"
printf '<%.5g>', 100.01; # stampa "<100.01>"
printf '<%.4g>', 100.01; # stampa "<100>"
Per i numeri interi, specificare una precisione implica che la formattazione del numero
sarà completata con zeri fino alla larghezza specificata:
printf '<%.6x>', 1; # stampa "<000001>"
printf '<%#.6x>', 1; # stampa "<0x000001>"
printf '<%-10.6x>', 1; # stampa "<000001 >"
Per le stringhe, specificando una precisione, la stringa sarà troncata per entrare
nella larghezza specificata:
printf '<%.5s>', "troncato"; # stampa "<tronc>"
printf '<%10.5s>', "troncato"; # stampa "< tronc>"
È anche possibile prendere la precisione dal prossimo argomento utilizzando .* :
printf '<%.6x>', 1; # stampa "<000001>"
printf '<%.*x>', 6, 1; # stampa "<000001>"
Attualmente non potete ottenere la precisione da un numero specifico, ma ci si aspetta che
venga implementato in futuro utilizzando ad esempio .*2$ :
printf '<%.*2$x>', 1, 6; # NON VALIDO, ma in futuro stampera` "<000001>"
- dimensione
-
Per i numeri, è possibile specificare la dimensione con cui questi devono essere
interpretati utilizzando
l , h , V , q , L , o ll . Per conversioni ad interi
(d u o x X b i D U O ), i numeri sono di norma interpretati secondo la dimensione di default
di un intero sulla vostra piattaforma (generalmente 32 o 64 bit), ma è possibile
invece utilizzare uno dei seguenti tipi standard del C, secondo il supporto del compilatore
utilizzato per compilare il Perl:
l intero interpretato come tipo C "long" o "unsigned long"
h intero interpretato come tipo C "short" o "unsigned short"
q, L o ll intero interpretato come tipo C "long long", "unsigned long long".
o "quads" (generalmente interi a 64 bit)
[``unsigned'' sta per ``senza segno'', NdT]
L'ultimo produrrà un errore se la vostra installazione del Perl non capisce i
``quads'' (questo richiede che la vostra piattaforma supporti nativamente i quad o che il
Perl sia stato specificamente compilato per supportarli). Potete verificare se il vostro
Perl supporta i quad utilizzando Config:
use Config;
($Config{use64bitint} eq 'define' || $Config{longsize} >= 8) &&
print "quads\n";
Per conversioni a virgola mobile (e f g E F G ), i numeri sono interpretati di norma secondo
la dimensione di default di un numero a virgola mobile sulla vostra piattaforma (double o long
double), ma si può forzare l'utilizzo di 'long double' con q , L , o ll se la
vostra piattaforma lo supporta. Potete verificare se il vostro Perl supporta i long double
utilizzando Config:
use Config;
$Config{d_longdbl} eq 'define' && print "long double\n";
Potete verificare che il Perl considera 'long double' come la dimensione di default per i
decimali a virgola mobile, utilizzando Config:
use Config;
($Config{uselongdouble} eq 'define') &&
print "long double sono il default\n";
È anche possibile che 'double' e 'long double' siano la stessa cosa:
use Config;
($Config{doublesize} == $Config{longdblsize}) &&
print "i double sono long double\n";
Il modificatore di dimensione V non ha alcun effetto nel codice Perl, ma è
supportato per compatibilità con il codice XS; vuol dire 'utilizza la dimensione
di default per un intero (o decimale)', che è già il default nel codice
Perl.
- ordine degli argomenti
-
Di solito, sprintf prende il prossimo argomento non utilizzato come valore da
formattare, per ogni identificatore di formato. Se l'identificatore utilizza
* per
richiedere argomenti aggiuntivi, questi vengono ``consumati'' dalla lista degli argomenti
nell'ordine in cui compaiono nel formato prima del valore da formattare. Dove un
argomento sia indicato da un indice esplicito, questo non modifica il normale ordinamento
degli argomenti (anche se l'indice specificato esplicitamente sarebbe stato comunque
il prossimo argomento).
Quindi:
printf '<%*.*s>', $a, $b, $c;
utilizza $a per la larghezza, $b per la precisione e $c come valore da
formattare, mentre:
print '<%*1$.*s>', $a, $b;
utilizza $a per la larghezza e la precisione e $b come valore da formattare.
Di seguito qualche ulteriore esempio; attenzione che utilizzando un indice esplicito, il
segno $ può aver bisogno di essere protetto:
printf "%2\$d %d\n", 12, 34; # stampa "34 12\n"
printf "%2\$d %d %d\n", 12, 34; # stampa "34 12 34\n"
printf "%3\$d %d %d\n", 12, 34, 56; # stampa "56 12 34\n"
printf "%2\$*3\$d %d\n", 12, 34, 3; # stampa " 34 12\n"
Se è stata data la direttiva use locale , il carattere utilizzato per il punto
decimale nei numeri non interi è dipendente dall'impostazione LC_NUMERIC.
Consultate perllocale.
- sqrt ESPR
-
- sqrt
-
Restituisce la radice quadrata di ESPR. Se ESPR viene omessa, restituisce la radice
quadrata di
$_ . Funziona solo su quantità non negative, a meno che non abbiate
caricato il modulo standard Math::Complex.
use Math::Complex;
print sqrt(-2); # stampa 1.4142135623731i
- srand ESPR
-
- srand
-
Imposta il seme del generatore di numeri casuali per
l'operatore
rand .
Lo scopo della funzione è seminare [``to seed'' in iglese, NdT]
la funzione rand affinché possa produrre una sequenza
diversa ogni volta che lanciate il vostro programma.
Se srand() non viene chiamata esplicitamente, verrà
chiamata implicitamente la prima volta che viene usato
rand . Comunque, questo non era il comportamento delle versioni
di Perl precedenti alla 5.004, quindi se il vostro script
si avvale di una vecchia versione dell'interprete, dovrebbe
chiamare srand .
La maggior parte dei programmi non chiameranno affatto
srand(), fatta eccezione per quelli che hanno bisogno di
un punto di partenza crittograficamente robusto
anziché quello di default, il quale basato sull'ora, l'ID del processo,
l'allocazione di memoria o il device /dev se disponibile, è
generalmente accettabile.
Potete chiamare srand($seme) con lo stesso $seme per
riottenere la medesima sequenza da rand(), ma di solito
questo si fa esclusivamente per generare risultati
prevedibili, per fare test o debugging.
Altrimenti, non chiamate srand() più di una volta
nei vostri programmi.
Non chiamate srand() (vale a dire, non chiamatela senza
argomenti) più di una volta in uno script. Lo
stato interno del generatore di numeri casuali dovrebbe
contenere più entropia di quella che può essere
fornita da qualunque seme, quindi chiamare srand()
un'altra volta di fatto causa una perdita di
casualità.
La maggior parte delle implementazioni di srand
prendono un intero e troncheranno la parte decimale
senza dire nulla. Questo significa che srand(42)
produrrà di solito gli stessi risultati di
srand(42.1) . Per andare sul sicuro, passate sempre
a srand valori interi.
Nelle versioni di Perl precedenti alla 5.004, il seme di
default era solo il valore corrente di time .
Non si tratta di un seme particolarmente buono, quindi
molti vecchi programmi forniscono un loro personale
valore per il seme (spesso time ^ $$ oppure
time ^ ($$ + ($$ << 15)) ), ma questo non è
più necessario.
Comunque, per ragioni crittografiche, vi serve qualcosa
di più casuale del seme di default.
Costruire un checksum dell'output compresso di uno o
più programmi che monitorano uno stato del
sistema operativo che cambia di frequente è il
modo che viene usato di solito. Ad esempio:
srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
Se tenete particolarmente a questo aspetto, date un'occhiata
al modulo Math::TrulyRandom su CPAN.
I programmi (come gli script CGI) che vengono usati frequentemente e che fanno uso di
time ^ $$
possono cadere preda della proprietà matematica che
a^b == (a+1)^(b+1)
un terzo delle volte. Quindi non fatelo.
- stat FILEHANDLE
-
- stat ESPR
-
- stat
-
Restituisce una lista di 13 elementi che forniscono le informazioni di stato per un file, sia
che il file sia aperto tramite FILEHANDLE, sia che venga fissato da ESPR. Se ESPR viene omessa,
stat viene eseguito su
$_ . Restituisce una lista nulla se la stat fallisce.
Viene tipicamente usata nella maniera seguente:
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat($nomefile);
Va notato che tutti i campi sono supportati su tutti i tipi di filesystem. Ecco i significati
dei campi:
0 dev numero di device del filesystem
1 ino numero di inode
2 mode modalita` del file (tipo e permessi)
3 nlink numero di (hard) link al file
4 uid ID numerico dell'utente del proprietario del file
5 gid ID numerico del gruppo del proprietario del file
6 rdev l'identificativo di device (solo file speciali)
7 size dimensione totale del file, in byte
8 atime istante in secondi dell'ultimo accesso dall'epoch
9 mtime istante in secondi dell'ultima modifica dall'epoch
10 ctime istante in secondi di modifica dell'inode dall'epoch (*)
11 blksize dimensione preferita dei blocchi per l'I/O del filesystem
12 blocks numero di blocchi realmente allocati
(L'epoch è stato alle 00:00 del 1 gennaio 1970 GMT).
(*) Non tutti i campi sono supportati da tutti i tipi di filesystem. Degno di nota il fatto che
il campo ctime non è portabile. In particolare non ci si può aspettare esso sia
un ``tempo di creazione'', si veda perlport/``Files and Filesystems''
[``File e Filesystem'', NdT] per dettagli.
Se a stat viene passato lo speciale filehandle che consiste in un carattere di sottolineatura,
non viene eseguita alcuna stat ma vengono restituiti i contenuti correnti della struttura di
stat provenienti dall'ultima stat , lstat o filestat . Ad esempio:
if (-x $file && (($d) = stat(_)) && $d < 0) {
print "$file e` un file NFS eseguibile\n";
}
(Questo funziona solo su elaboratori per i quali il numero di device è negativo sotto
NFS).
Visto che la modalità contiene sia il tipo di file che i suoi permessi, se volete
vedere gli effettivi permessi dovreste mascherare la porzione relativa al tipo di file e
utilizzare (s)printf usando un "%o" .
$modalita = (stat($nomefile))[2];
printf "I permessi sono %04o\n", $modalita & 07777;
In un contesto scalare, stat restituisce un valore booleano che indica il
successo o l'insuccesso e, in caso di successo, imposta l'informazione associata con lo
speciale filehandle _ .
Il modulo File::stat fornisce un conveniente meccanismo di accesso mediante nome:
use File::stat;
$sb = stat($nomefile);
printf "Il file e` %s, la dimensione e` %s, perm %04o, mtime %s\n",
$nomefile, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;
Potete importare le costanti (S_IF* ) e funzioni (S_IS* ) delle
modalità simboliche, dal modulo Fcntl:
use Fcntl ':mode';
$modalita = (stat($nomefile))[2];
$utente_rwx = ($modalita & S_IRWXU) >> 6;
$gruppo_lettura = ($modalita & S_IRGRP) >> 3;
$altri_esecuzione = $modalita & S_IXOTH;
printf "I permessi sono %04o\n", S_IMODE($modalita), "\n";
$e_setuid = $modalita & S_ISUID;
$e_setgid = S_ISDIR($modalita);
Potete scrivere le ultime due utilizzando gli operatori -u e -d . Le costanti S_IF*
comunemente disponibili sono
# Permessi: lettura, scrittura, esecuzione, per l'utente, gruppo, altri.
S_IRWXU S_IRUSR S_IWUSR S_IXUSR
S_IRWXG S_IRGRP S_IWGRP S_IXGRP
S_IRWXO S_IROTH S_IWOTH S_IXOTH
# Setuid/Setgid/Relativo allo sticky bit/SaveText.
# Va notato che l'esatto significato di questi, e` dipendente dal sistema.
S_ISUID S_ISGID S_ISVTX S_ISTXT
# Tipi di file. Non tutti sono necessariamente disponibili sul vostro sistema.
S_IFREG S_IFDIR S_IFLNK S_IFBLK S_IFCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT
# Le seguenti sono alias di compatibilita` per S_IRUSR, S_IWUSR, S_IXUSR.
S_IREAD S_IWRITE S_IEXEC
e le funzioni S_IF* sono
S_IMODE($modalita) la parte di $modalita contenente i bit dei permessi
e i bit di setuid/setgid/sticky
S_IFMT($modalita) la parte di $modalita contenente il tipo del file
che puo` essere fatta oggetto di un and su bit con ad esempio
S_IFREG o con le seguenti funzioni
# Gli operatori -f, -d, -l, -b, -c, -p e -S.
S_ISREG($modalita) S_ISDIR($modalita) S_ISLNK($modalita)
S_ISBLK($modalita) S_ISCHR($modalita) S_ISFIFO($modalita) S_ISSOCK($modalita)
# Non esiste una controparte all'operatore -X ma, per il primo,
# l'operatore -g e` spesso equivalente. L'ENFMT sta per
# record flocking enforcement [l'applicazione forzata del flock ad un record, NdT],
# una caratteristica indipendente dalla piattaforma.
S_ISENFMT($modalita) S_ISWHT($modalita)
Consultate la vostra documentazione locale di chmod(2) e stat(2) per maggiori dettagli sulle
costanti S_* . Per ottenere l'informazione dello stato per un link simbolico, utilizzate la
funzione lstat invece del file puntato dal link.
- study SCALARE
-
- study
-
Impiega del tempo addizionale per studiare lo SCALARE (
$_ se non viene
specificato) in previsione di un gran numero di corrispondenze del pattern
sulla stringa, prima che sia modificata. Può far risparmiare
tempo o meno, a seconda della natura e del numero di pattern che state
cercando, e della distribuzione delle frequenze di caratteri nella
stringa da cercare, probabilmente vale la pena di confrontare i tempi
di esecuzione con o senza study per vedere quale è più veloce.
I cicli che controllano la presenza di brevi e numerose stringhe costanti
(inclusa la parte costante di pattern più complessi) ne beneficeranno
in maggior misura. Potete avere una sola study attiva per volta, se
``studiate'' uno scalare diverso il primo è ``non studiato''. (La maniera
in cui funziona study è la seguente: viene generata una lista
concatenata di ogni carattere nella stringa, in modo tale da conoscere,
per esempio, dove stanno tutti i caratteri 'k' . Da ogni stringa di
ricerca, viene selezionato il carattere più raro, secondo delle tabelle
statiche di frequenza, costruite con alcuni programmi C e del testo in
inglese. Vengono esaminate solo le posizioni che contengono questi caratteri
``più rari'').
Per esempio, ecco un ciclo che inserisce un indice producendo delle annotazioni
prima di ogni linea che contiene un certo pattern:
while (<>) {
study;
print ".IX pippo\n" if /\bpippo\b/;
print ".IX pluto\n" if /\bpluto\b/;
print ".IX paperino\n" if /\bpaperino\b/;
# ...
print;
}
Cercando /\bpippo\b , verranno controllati solo le posizioni in $_ che
contengono p , poiché essa è più rara di o .
In generale, e fatta eccezione per i casi patologici, si ottiene un grande
vantaggio. L'unico problema è se viene risparmiato più tempo
di quanto se ne perde inizialmente per costruire la lista linkata.
Va notato che se dovete cercare stringhe che non conoscerete se non quando
il programma sarà eseguito, potete costruire l'intero loop come una
stringa, e valutare quest'ultima per evitare la ricompilazione dei
pattern tutte le volte. Messo assieme alla pratica di rendere indefinito
$/ per leggere interi file come fossero un solo record, il tutto può
risultare molto veloce, spesso più veloce di fgrep(1). Il codice che
segue controlla una lista di file (@files ) cercando una lista di
parole (@parole ), e stampa i nomi dei file che contengono una
corrispondenza:
$cerca = 'while (<>) { study;';
foreach $parola (@parole) {
$cerca .= "++\$viste{\$ARGV} if /\\b$parola\\b/;\n";
}
$cerca .= "}";
@ARGV = @files;
undef $/;
eval $cerca; # questa salta all'occhio
$/ = "\n"; # rimette il normale delimitatore di input
foreach $file (sort keys(%viste)) {
print $file, "\n";
}
- sub NOME BLOCCO
-
- sub NOME (PROTO) BLOCCO
-
- sub NOME : ATTRIBUTI BLOCCO
-
- sub NOME (PROTO) : ATTRIBUTI BLOCCO
-
Questa è la definizione di subroutine, non una vera funzione di per sé.
Senza un BLOCCO è semplicemente una dichiarazione a posteriori. Senza un NOME è
una dichiarazione di funzione anonima ed in effetti restituisce un valore: il riferimento al
CODICE della chiusura che avete appena creato.
Consultate perlsub e perlref per dettagli sulle subroutine e i riferimenti, attributes
e the Attribute::Handlers manpage per maggiori informazioni sugli attributi.
- substr ESPR,SCOSTAMENTO,LUNGHEZZA,SOSTITUZIONE
-
- substr ESPR,SCOSTAMENTO,LUNGHEZZA
-
- substr ESPR,SCOSTAMENTO
-
Estrae una sottostringa da ESPR e la restituisce. Il primo carattere è a scostamento
0 , oppure la qualsivoglia impostazione data a $[ (ma non è consigliabile farlo).
Se SCOSTAMENTO è un numero negativo (o più precisamente, minore di $[ ), viene
contato dalla fine della stringa. Se LUNGHEZZA viene omesso, restituisce tutto ciò che
rimane fino alla fine della stringa. Se LUNGHEZZA è un numero negativo, rimuove il
numero specificato di caratteri dalla fine della stringa.
Potete usare la funzione substr() come valore assegnabile, nel qual caso ESPR
deve essere a sua volta un valore assegnabile. Se assegnate qualcosa di più
corto di LUNGHEZZA, la stringa viene ridotta, mentre se assegnate qualcosa di più lungo
di LUNGHEZZA, la stringa viene allungata per fargli posto. Per mantenere la stringa della
stessa lunghezza, potrebbe essere necessario riempire lo spazio che avanza o eliminare i
valori in eccesso utilizzando sprintf .
Se SCOSTAMENTO e LUNGHEZZA specificano una sottostringa che è parzialmente al di fuori
della stringa, solo la parte dentro la stringa viene restituita. Se la sottostringa è
oltre entrambi gli estremi della stringa, substr() restituisce il valore indefinito e produce
un avvertimento. Quando viene utilizzata come valore assegnabile, specificare una sottostringa
interamente al di fuori della stringa è un errore bloccante. Di seguito un esempio che
mostra il comportamento per i casi limite:
my $nome = 'fred';
substr($nome, 4) = 'dy'; # $nome contiene ora 'freddy'
my $nulla = substr $nome, 6, 2; # restituisce '' (senza warning)
my $oops = substr $nome, 7; # restituisce undef, con warning
substr($nome, 7) = 'gap'; # errore bloccante
Un'alternativa all'utilizzo di substr() come valore assegnabile è quella di specificare
un valore da sostituire come quarto argomento. Questo permette di sostituire una parte di ESPR e
restituisce ciò che c'era in quella parte prima dell'operazione, proprio come fa
splice().
- symlink VECCHIOFILE,NUOVOFILE
-
Crea un nuovo nome di file, collegato simbolicamente a quello vecchio. Restituisce
1 in caso
di successo, 0 altrimenti. Sui sistemi che non supportano i link simbolici, genera un
errore bloccante a tempo di esecuzione. Per controllare ciò, usate eval:
$esiste_symlink = eval { symlink("",""); 1 };
- syscall NUMERO,LISTA
-
Invoca la chiamata di sistema specificata come primo elemento della lista, passando i rimanenti
elementi come argomenti alla chiamata di sistema. Se non implementata, produce un errore
bloccante. Gli argomenti sono interpretati come segue: se un dato argomento è numerico,
l'argomento è passato come un intero. Se non lo è, viene passato il puntatore al
valore della stringa. Siete responsabili nell'assicurarvi che una stringa sia sia estesa
in anticipo in misura tale da ricevere qualunque risultato che possa essere scritto in una
stringa. Non potete utilizzare una stringa letterale (o altre stringhe di sola lettura)
come argomento di
syscall perché il Perl deve assumere che ogni puntatore a stringa
possa essere scritto dall'inizio alla fine. Se gli argomenti numerici non sono letterali e non
sono mai stati interpretati in un contesto numerico, si rende necessario sommare ad essi 0
per forzarli nell'apparire come numeri. Quanto segue emula la funzione syswrite (o
viceversa):
require 'syscall.ph'; # potrebbe essere necessario eseguire h2ph
$s = "ehila`\n";
syscall(&SYS_write, fileno(STDOUT), $s, length $s);
Va notato che il Perl supporta il passaggio fino ad un massimo di 14 argomenti per la vostra
chiamata di sistema, che in pratica di solito dovrebbe essere sufficiente.
Syscall restituisce qualunque valore sia stato restituito dalla chiamata di sistema che essa ha
invocato. Se la chiamata di sistema fallisce, syscall restituisce -1 ed imposta $!
(errno). Va notato che alcune chiamate di sistema possono legittimamente restituire -1 .
La maniera appropriata per gestire tali chiamate è quella di assegnare $!=0;
prima della chiamata e controllare il valore di $! se syscall restituisce -1 .
C'è un problema con syscall(&SYS_pipe) : essa restituisce il numero di file
dell'estremità in lettura della pipe che ha creato. Non c'è alcun modo per
recuperare il numero di file dell'altro capo. Si può evitare questo problema
utilizzando piuttosto pipe .
- sysopen FILEHANDLE,NOMEFILE,MODALITÀ
-
- sysopen FILEHANDLE,NOMEFILE,MODALITÀ,PERMESSI
-
Apre il file il cui nome è dato da NOMEFILE e lo associa a FILEHANDLE. Se FILEHANDLE
è un'espressione, il suo valore viene usato come nome del vero filehandle che occorre.
Questa funzione richiama la funzione
open del sistema operativo sottostante, con i parametri
NOMEFILE, MODALITÀ, PERMESSI.
I possibili valori e i bit di flag del parametro MODALITÀ sono dipendenti dal sistema;
sono disponibili mediante il modulo standard Fcntl . Consultate la documentazione della
open del vostro sistema operativo per rendersi conto di quali valori e bit di flag sono
disponibili. Potete mettere assieme diversi flag utilizzando il | -operatore.
Alcuni dei più comuni valori sono O_RDONLY per aprire il file in modalità di
sola lettura, O_WRONLY per aprire il file in modalità di sola scrittura e O_RDWR
per aprire il file in modalità di lettura-scrittura.
Per ragioni storiche, alcuni valori funzionano su pressoché tutti i sistemi supportati
dal perl: zero significa di sola lettura, uno significa di sola scrittura
e due significa lettura/scrittura. Si è a conoscenza che questi valori non
funzionano sotto OS/390 & VM/ESA Unix e sul Macintosh; è probabile che non vogliate
usarli in nuovo codice.
Se il file fissato da NOMEFILE non esiste e la chiamata open lo crea (tipicamente
perché MODALITÀ include il flag O_CREAT ), allora il valore di PERMESSI
specifica i permessi del file appena creato. Se a sysopen omettete l'argomento PERMESSI, il
Perl utilizza il valore ottale 0666 . Questi valori dei permessi devono essere in ottale e
sono modificati dall'umask del processo corrente.
Su molti sistemi, il flag O_EXCL è disponibile per aprire i file in modalità
esclusiva. Questo non è eseguire un lock: l'esclusività significa in questo
contesto che se il file esiste già, sysopen() fallisce. O_EXCL potrebbe non funzionare
su filesystem di rete e non ha effetto a meno che venga impostato anche il flag O_CREAT .
Impostare O_CREAT|O_EXCL impedisce che il file venga aperto se è un link simbolico.
Questo non offre protezione ai link simbolici nel percorso del file.
Talvolta potreste voler troncare un file già esistente. Questo può essere
fatto utilizzando il flag O_TRUNC . Il comportamento di O_TRUNC con O_RDONLY è
indefinito.
0644 come argomento di sysopen andrebbe usato raramente, se non mai, poiché toglie
all'utente la possibilità di avere una umask più permissiva. È meglio
ometterlo. Consultate la voce perlfunc(1) su umask per maggiori dettagli.
Va notato che sysopen dipende dalla funzione di libreria C fdopen(). Su molti sistemi UNIX,
fdopen() è nota per fallire quando i descrittori dei file eccedono un certo valore,
tipicamente 255. Se avete bisogno di più descrittori di file, considerate la
possibilità di ricompilare il Perl in maniera che possa utilizzare la libreria sfio
o forse usando la funzione POSIX::open().
Consultate perlopentut per una gentile, garbata spiegazione sul come aprire i file.
- sysread FILEHANDLE,SCALARE,LUNGHEZZA,SCOSTAMENTO
-
- sysread FILEHANDLE,SCALARE,LUNGHEZZA
-
Cerca di leggere un numero di byte di dati pari a LUNGHEZZA nella variabile SCALARE dal
FILEHANDLE specificato, utilizzando la chiamata di funzione read(2). Essa aggira l'IO con
buffer, dunque mescolarla con altri tipi di read,
print , write , seek , tell o eof
potrebbe causare confusione visto che il perlio o lo stdio di solito utilizzano un buffer per
i dati. Restituisce il numero di caratteri effettivamente letti, 0 alla fine del file,
oppure undef se c'è stato un errore (in quest'ultimo caso viene anche impostato $! ).
SCALARE verrà aumentato o diminuito in maniera che l'ultimo byte effettivamente letto sia
l'ultimo byte dello scalare dopo la lettura.
Uno SCOSTAMENTO può essere specificato per posizionare i dati letti da qualche
parte della stringa che non sia l'inizio. Uno SCOSTAMENTO negativo specifica il posizionamento
a quel numero di caratteri, contando a ritroso a partire dalla fine della stringa.
Uno SCOSTAMENTO positivo maggiore della lunghezza dello SCALARE ha come risultato il riempimento
della stringa alla dimensione richiesta con dei byte "\0" prima che il risultato della lettura sia
avvenuto.
Non c'è una funzione syseof(), il che è ok, visto che comunque eof() non
funziona molto bene sui file di device (come ttys). Usate sysread() e controllate che il valore
restituito sia pari a 0 per decidere se si ha concluso.
Va notato che se il filehandle è stato marcato come :utf8 , verranno scritti
caratteri Unicode invece di byte (la LUNGHEZZA, lo SCOSTAMENTO e il valore restituito da
sysread() sono in caratteri Unicode). Lo strato :encoding(...) introduce implicitamente lo
strato :utf8 . Consultate binmode, open e la direttiva di open , open.
- sysseek FILEHANDLE,POSIZIONE,DA_DOVE
-
Imposta la posizione di sistema del FILEHANDLE in byte, usando la chiamata di sistema
lseek(2). FILEHANDLE può essere un'espressione il cui valore fornisce il nome del
filehandle. I valori per DA_DOVE sono
0 per impostare la nuova posizione a POSIZIONE, 1
per impostarla alla posizione corrente più POSIZIONE e 2 per impostarla ad EOF
più POSIZIONE (tipicamente negativa).
Notate l'in byte: anche se il filehandle è stato impostato per operare su caratteri
(per esempio usando lo strato di I/O :utf8 ), tell() restituirà scostamenti di byte,
non scostamenti di caratteri (visto che implementare questo renderebbe sysseek() molto lenta).
sysseek() aggira il normale IO con buffer, dunque unire questo con i vari read (oltre a
sysread , per esempio <> oppure read()), print , write , seek , tell o eof ,
potrebbe causare confusione.
Per DA_DOVE, si potrebbe anche usare le costanti SEEK_SET , SEEK_CUR e SEEK_END (inizio
del file, posizione corrente, fine del file) dal modulo Fcntl. L'uso delle costanti è
anche più portabile che fare affidamento su 0, 1 e 2. Per esempio, per definire una
funzione ``systell'':
use Fnctl 'SEEK_CUR';
sub systell { sysseek($_[0], 0, SEEK_CUR) }
Restituisce la nuova posizione oppure il valore indefinito in caso di insuccesso. Un valore di
posizione pari a zero viene restituito sotto forma della stringa "0 ma vero" ; dunque
sysseek restituisce vero in caso di successo e falso in caso di insuccesso, tuttavia la
nuova posizione può ancora essere determinata facilmente.
- system LISTA
-
- system PROGRAMMA LISTA
-
Fa esattamente la stessa cosa di
exec LISTA , salvo che viene eseguito prima un fork e che il
processo genitore aspetta che il processo figlio abbia ultimato. Va notato che il trattamento
degli argomenti varia in relazione al numero di argomenti. Se c'è più di un
argomento nella LISTA oppure se la LISTA è un array con più di un valore, fa
partire il programma fornendo il primo elemento della lista con argomenti forniti dal resto
della lista. Se c'è solo un argomento scalare, 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.
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 ogni operazione che potrebbe eseguire un fork, 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.
Il valore restituito è lo stato di uscita del programma come restituito dalla chiamata
wait . Per ottenere il valore di uscita corrente, fate uno shift a destra di otto (guardate
di seguito). Consultate anche exec. Questo non è quello che avete bisogno di
usare per catturare l'output da un comando, per questo dovreste usare soltanto le
virgolette inverse oppure qx// come descritto in perlop/```STRING`''. Un valore restituito
pari a -1 indica un insuccesso nel far eseguire il programma oppure un errore della chiamata di
sistema wait(2) (esaminate $! per il motivo).
Come exec , system permette di mentire ad un programma riguardo al proprio nome se si usa
la sintassi system PROGRAMMA LISTA . Di nuovo, si veda exec.
Dato che system e le virgolette inverse bloccano SIGINT e SIGQUIT , eseguire un
kill sul programma che essi stanno eseguendo non interromperà realmente il
programma.
Visto che SIGINT e SIGQUIT vengono ignorati durante l'esecuzione di system ,
se vi aspettate che il vostro programma termini sulla ricezione di questi segnali,
avrete bisogno di fare in modo di farlo voi stessi, in base al valore restituito.
@args = ("comando", "arg1", "arg2");
system(@args) == 0
or die "system @args e` fallito: $?"
Potete controllare tutte le possibilità di insuccesso, ispezionando $? come in
questo caso:
if ($? == -1) {
print "fallimento nell'esecuzione: $!\n";
}
elsif ($? & 127) {
printf "figlio morto con segnale %d, %s coredump\n",
($? & 127), ($? & 128) ? 'con' : 'senza';
}
else {
printf "figlio uscito con valore %d\n", $? >> 8;
}
oppure in maniera più portabile usando le chiamate W*() dell'estensione POSIX; si
veda perlport per maggiori informazioni.
Quando gli argomenti vengono fatti eseguire mediante la shell di sistema, i risultati e i
codici che vengono restituiti saranno soggetti ai suoi vezzi e proprietà. Consultate
perlop/```STRING`'' e exec per i dettagli.
- syswrite FILEHANDLE,SCALARE,LUNGHEZZA,SCOSTAMENTO
-
- syswrite FILEHANDLE,SCALARE,LUNGHEZZA
-
- syswrite FILEHANDLE,SCALARE
-
Tenta di scrivere un numero di caratteri di informazioni, pari a LUNGHEZZA, dalla variabile
SCALARE al FILEHANDLE specificato, usando la chiamata di sistema write(2). Se LUNGHEZZA
non è specificata, scrive l'intero SCALARE. Elude l'IO con buffer, dunque
mescolarla con i vari read (oltre a
sysread() ), print , write , seek , tell o
eof , potrebbe causare confusione visto che lo stdio di solito utilizza un buffer per i
dati. Restituisce il numero di caratteri effettivamente scritti oppure undef se
c'è stato un errore (in questo caso viene anche impostata la variabile errno $! ).
Se la LUNGHEZZA è più grande dei dati disponibili nello scalare dopo lo SCOSTAMENTO,
verrà scritto solo il maggior numero di dati disponibili.
Uno SCOSTAMENTO può essere specificato per scrivere i dati a partire da qualche
parte della stringa che non sia l'inizio. Uno SCOSTAMENTO negativo specifica la scrittura
di quel numero di caratteri, contando a ritroso a partire dalla fine della stringa.
Nel caso lo SCALARE sia vuoto, si può usare SCOSTAMENTO ma solo uno scostamento
pari a zero.
Va notato che se il filehandle è stato marcato come :utf8 , verranno scritti
caratteri Unicode invece di byte (la LUNGHEZZA, lo SCOSTAMENTO e il valore restituito di
syswrite() sono in caratteri Unicode codificati UTF-8). Lo strato :encoding(...)
introduce implicitamente lo strato :utf8 .
Consultate binmode, open e la direttiva di open , open.
- tell FILEHANDLE
-
- tell
-
Restituisce la posizione corrente in byte per il FILEHANDLE oppure -1 in caso di
errore. FILEHANDLE può essere un'espressione il cui valore fornisce il nome del
FILEHANDLE corrente. Se FILEHANDLE viene omesso, prende in considerazione l'ultimo file
letto.
Va notato l'in byte: anche se il filehandle è stato impostato per operare su
caratteri (per esempio usando l'open layer :utf8 ), tell() restituirà
scostamenti di byte e non scostamenti di caratteri (questo perché renderebbe
seek() e tell() piuttosto lenti).
Il valore restituito da tell() per i flussi standard come lo STDIN, dipende dal sistema
operativo: potrebbe restituire -1 o qualcos'altro. tell() sulle pipe, fifo e socket di
solito restituisce -1.
Non c'è una funzione systell . Per questo, si usi sysseek(FH, 0, 1) .
Non usate tell() (o altre operazione di I/O che usano un buffer) su un filehandle che sia
stato manipolato da sysread(), syswrite() o sysseek(). Queste funzioni ignorano l'utilizzo di
buffer mentre tell() no.
- telldir DIRHANDLE
-
Restituisce la posizione corrente delle routine
readdir su DIRHANDLE. Il valore
ottenuto può essere passato a seekdir per accedere ad una particolare
locazione in una directory. telldir ha gli stessi avvertimenti sulla directory
compaction [compattazione della directory, NdT] della corrispondente routine della
libreria di sistema.
- tie VARIABILE,NOMECLASSE,LISTA
-
Questa funziona collega una variabile ad una classe (un package), la quale
fornirà l'implementazione per la variabile. VARIABILE è il nome della
variabile da incantare. NOMECLASSE è il nome di una classe che implementa
oggetti del tipo corretto. Eventuali argomenti addizionali sono passati al metodo
new
della classe (cioè TIESCALAR , TIEHANDLE , TIEARRAY o TIEHASH ).
Tipicamente questi sono argomenti simili a quelli che si potrebbero passare alla funzione
dbm_open() del C. L'oggetto restituito dal metodo new è anche restituito
dalla funzione tie , e risulta utile per accedere ad altri metodi in NOMECLASSE.
Va notato che funzioni come keys e values possono restituire liste molto grandi
quando vengono usate su oggetti grandi, come file DBM. Potreste preferire l'utilizzo
della funzione each per iterare su tali strutture. Ad esempio:
# stampa gli offset del file history
use NDBM_File;
tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
while (($chiave,$val) = each %HIST) {
print $chiave, ' = ', unpack('L',$val), "\n";
}
untie(%HIST);
Una classe che implementa un hash deve contenere i seguenti metodi:
TIEHASH nomeclasse, LISTA
FETCH this, chiave
STORE this, chiave, valore
DELETE this, chiave
CLEAR this
EXISTS this, chiave
FIRSTKEY this
NEXTKEY this, ultimachiave
DESTROY this
UNTIE this
Un classe che implementa un array ordinario deve contenere i seguenti metodi:
TIEARRAY nomeclasse, LISTA
FETCH this, chiave
STORE this, chiave, valore
FETCHSIZE this
STORESIZE this, conteggio
CLEAR this
PUSH this, LISTA
POP this
SHIFT this
UNSHIFT this, LISTA
SPLICE this, scostamento, lunghezza, LISTA
EXTEND this, conteggio
DESTROY this
UNTIE this
Un classe che implementa un file handle deve contenere i seguenti metodi:
TIEHANDLE nomeclasse, LISTA
READ this, scalare, lunghezza, scostamento
READLINE this
GETC this
WRITE this, scalare, lunghezza, scostamento
PRINT this, LISTA
PRINTF this, formato, LISTA
BINMODE this
EOF this
FILENO this
SEEK this, posizione, dadove
TELL this
OPEN this, modo, LISTA
CLOSE this
DESTROY this
UNTIE this
Una classe che implementa uno scalare deve contenere i seguenti metodi:
TIESCALAR nomeclasse, LISTA
FETCH this,
STORE this, valore
DESTROY this
UNTIE this
Non è necessario implementare tutti i metodi sopra descritti. Consultate
perltie, the Tie::Hash manpage, the Tie::Array manpage, the Tie::Scalar manpage e the Tie::Handle manpage.
A differenza di dbmopen , la funzione tie non chiamerà use o require per
voi su un modulo, dovrete farlo voi esplicitamente. Consultate DB_File o il modulo
Config per delle interessanti implementazioni di tie .
Per ulteriori dettagli consultate perltie, tied VARIABLE [``VARIABILE legata'', NdT].
- tied VARIABILE
-
Restituisce un riferimento all'oggetto a cui si riferisce VARIABILE (lo stesso valore
che originariamente era stato restituito dalla chiamata a
tie che ha legato la
variabile al package.) Restituisce il valore indefinito se VARIABILE non è
legata ad un package.
- time
-
Restituisce il numero di secondi, senza tenere conto dei leap second
[secondi di aggiustamento, NdT], dalla data che il sistema considera essere l'epoch,
adatto per alimentare
gmtime e localtime . Sulla maggior parte dei sistemi, l'epoch
è 00:00:00 UTC, Gennaio 1, 1970; una importante eccezione è costituita da
Mac OS Classic il quale utilizza come epoch 00:00:00, January 1, 1904 nella zona temporale del
locale corrente.
Per misurare il tempo con precisione maggiore di un secondo, potete utilizzare il modulo
Time::HiRes (da CPAN e, a partire dal Perl 5.8, parte della distribuzione standard),
oppure se avete a disposizione gettimeofday(2), potreste essere in grado di utilizzare
l'interfaccia syscall del Perl. Consultate perlfaq8 per dettagli.
- times
-
Restituisce una lista di quattro elementi dando il times utente e di sistema, in
secondi, per il processo corrente e per i figli di questo processo.
($utente,$sistema,$figlioutente,$figliosistema) = times;
In un contesto scalare, times restituisce $utente .
- tr///
-
L'operatore di traslitterazione. Lo stesso che
y/// . Consultate perlop.
- truncate FILEHANDLE,LUNGHEZZA
-
- truncate ESPR,LUNGHEZZA
-
Tronca il file aperto sul FILEHANDLE, o chiamato con ESPR, alla lunghezza specificata.
Produce un errore bloccante se truncate non è implementata sul vostro sistema.
Restituisce vero se ha successo, il valore indefinito altrimenti.
Il comportamento è indefinito se LUNGHEZZA è più grande della
lunghezza del file.
- uc ESPR
-
- uc
-
Restituisce una versione di ESPR con lettere maiuscole. Questa è la funzione
interna che implementa l'escape
\U nelle stringhe tra apici doppi. Rispetta
l'LC_CTYPE locale corrente se use locale è attivo. Consultate perllocale e
perlunicode per maggiori dettagli riguardo locale e il supporto a Unicode. Non tenta
di eseguire un titlecase mapping [trasformazione in lettera maiuscola per Unicode, NdT]
sulle lettere iniziali delle parole. Per quello, consultate ucfirst .
Se ESPR viene omessa, la funzione usa $_ .
- ucfirst ESPR
-
- ucfirst
-
Restituisce il valore di ESPR con il primo carattere convertito in maiuscolo (titlecase
in terminologia Unicode). 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 $_ .
- umask ESPR
-
- umask
-
Imposta l'umask per il processo a ESPR e restituisce il precedente valore.
Se ESPR viene omessa, restituisce solamente l'umask corrente.
Il permesso Unix rwxr-x--- viene rappresentato come tre insiemi di tre bit oppure con
tre cifre ottali: 0750 (il primo 0 indica l'ottale e non è una delle cifre).
Il valore di umask è quel numero che rappresenta i bit dei permessi
disabilitati. I valori dei permessi (o ``modalità'') che passate a mkdir o
sysopen sono modificati dall'umask dunque anche se dite a sysopen di creare un
file con permessi 0777 , se l'umask è 0022 allora il file verrà in
effetti creato con permessi 0755 . Se l'umask fosse 0027 (il gruppo non
può scrivere, i restanti non possono leggere, scrivere od eseguire) allora
passare 0666 a sysopen creerebbe un file con modalità 0640
(0666 &~027 è 0640 ).
Ecco alcuni consigli: fornite una modalità di creazione di 0666 per file
ordinari (in sysopen ) ed una di 0777 per le directory (in mkdir ) e i file
eseguibili. Questo dà agli utenti la libertà di scelta: se vogliono file
protetti sceglieranno umask di 022 , 027 o anche la particolare ed antisociale mask
di 077 . I programmi, se non in rari casi, non dovrebbero prendere decisioni sulla
policy che sarebbe meglio fosse lasciata all'utente. L'eccezione a questo fatto si ha
nello scrivere file che devono essere mantenuti privati: file di mail, cookie del
browser web, file .rhosts e così via.
Se umask(2) non è implementata sul vostro sistema e si sta cercando di
restringere l'accesso a se stessi (cioè, (ESPR & 0700) > 0), produce un
errore bloccante a tempo di esecuzione. Se umask(2) non è implementata e non si
sta cercando di restringere l'accesso a se stessi, restituisce undef .
Ricordatevi che un umask è un numero, generalmente fornito in ottale; non
è una stringa di cifre ottali. Si veda anche oct se tutto ciò che
si ha è una stringa.
- undef ESPR
-
- undef
-
Rende indefinito il valore di ESPR, che deve essere un lvalue [un valore che può
trovarsi a sinistra di un operatore di assegnamento, NdT]. Si usa solo su un valore
scalare, un array (utilizzando
@ ), un hash (utilizzando % ), una subroutine
(utilizzando & ), oppure un typeglob (utilizzando * ). (undef $hash{$chiave}
probabilmente non farà ciò che ci si aspetta su molte variabili
predefinite o valori di liste DBM, dunque non fatelo; si veda delete).
Restituisce sempre il valore indefinito. Potete omettere l'ESPR, in tal caso non
viene reso indefinito niente, ma otterrete ancora un valore indefinito che si potreste,
per esempio, restituire da una subroutine, assegnare ad una variabile o passare come
parametro. Esempi:
undef $pippo;
undef $pluto{'nomeassurdo'}; # Confrontate con: delete $pippo{'nomeassurdo'};
undef @ary;
undef %hash;
undef &miasub;
undef *xyz; # distrugge $xyz, @xyz, %xyz, &xyz, ecc.
return (wantarray ? (undef, $msgerr) : undef) if $lo_hanno_saltato;
select undef, undef, undef, 0.25;
($a, $b, undef, $c) = &pippo; # Ignora il terzo valore restituito
Va notato che questo è un operatore unario, non un operatore di lista.
- unlink LISTA
-
- unlink
-
Cancella una lista di file. Restituisce il numero di file cancellati con successo.
$cnt = unlink 'a', 'b', 'c';
unlink @dacancellare;
unlink <*.bak>;
Nota: unlink non tenterà di cancellare le directory a meno che non siate
superuser e al Perl non venga passato il flag -U. Anche se queste condizioni risultano
soddisfatte, sappiate che effettuare un unlink su una directory può danneggiare
seriamente il vostro filesystem. Infine, usare unlink sulle directory non è
supportato su molti sistemi operativi. Usate rmdir al suo posto.
Se LISTA viene omessa, viene usato $_ .
- unpack TEMPLATE,ESPR
-
unpack è l'inverso di pack : prende una stringa e la espande in una lista di
valori. (In contesto scalare restituisce solamente il primo valore generato).
La stringa viene divisa in pezzi come descritto da TEMPLATE. Ogni pezzo viene convertito
separatamente in un valore. Solitamente, la stringa è un risultato di pack ,
oppure i suoi byte rappresentano una struttura C di un qualche tipo.
TEMPLATE ha lo stesso formato che nella funzione pack . Ecco una subroutine che trova
una sottostringa:
sub substr {
my($cosa,$dove,$quanto) = @_;
unpack("x$dove a$quanto", $cosa);
}
e poi c'è:
sub ordinale { unpack("c",$_[0]); } # come ord()
In aggiunta ai campi permessi da pack(), potete far precedere a ciascun campo un
%<numero> per indicare che desiderate un checksum di <numero>-bit degli elementi
anziché i reali elementi. Il checksum predefinito è di 16 bit.
Il checksum è calcolato sommando i valori numerici dei valori espandi (per le
stringhe viene considerata la somma di ord($carattere) , per i bit la somma degli zero
e degli uno).
Per esempio, il seguente codice calcola lo stesso numero del programma sum di System V:
$checksum = do {
local $/; # slurp!
unpack("%32C*",<>) % 65535;
};
Il seguente codice conta in maniera efficiente il numero di bit impostati in un vettore
di bit:
$bitimpostati = unpack("%32b*", $maschera_di_selezione);
I formati p e P devono essere usati con cura. Dato che Perl non ha alcun modo di
controllare se il valore passato ad unpack() corrisponda ad una valida locazione di
memoria, passare un puntatore che non si è certi sia valido probabilmente
porterà a conseguenze disastrose.
Se ci sono più codici per pack oppure se l conteggio delle ripetizioni di un
campo o di un gruppo è maggiore di quanto il rimanente input permetta, il
risultato non è ben definito: in alcuni casi, il conto delle ripetizioni viene
decrementato, oppure unpack() produrrà stringhe nulle o zeri oppure
terminerà con un errore. Se la stringa in input è più lunga di
quella descritta da TEMPLATE, la parte in più viene ignorata.
Consultate pack per ulteriori esempi e note.
- untie VARIABILE
-
Rompe il legame tra una variabile ed un package. (Si veda
tie ).
Non ha effetto se sulla variabile non è stato fatto un tie .
- unshift ARRAY,LISTA
-
Fa l'opposto di uno
shift . Oppure l'opposto di un push , a seconda di come lo si
guardi. Antepone una lista nella parte anteriore dell'array e restituisce il nuovo numero
di elementi nell'array.
unshift(@ARGV, '-e') unless $ARGV[0] =~ /^-/;
Va notato che LISTA viene anteposta per intero, non un elemento alla volta, dunque gli
elementi preposti si trovano nel medesimo ordine. Usate reverse per effettuare
l'inversione.
- use Modulo VERSIONE LISTA
-
- use Modulo VERSIONE
-
- use Modulo LISTA
-
- use Modulo
-
- use VERSIONE
-
Importa nel package corrente alcune semantiche dal modulo indicato, in generale creando
un alias per determinate subroutine all'interno del vostro package. È esattamente
equivalente a:
BEGIN { require Modulo; import Modulo LISTA; }
tranne per il fatto che Modulo deve essere una bareword (*).
VERSIONE può essere sia un argomento numerico come 5.006, il quale 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. Fate un confronto con require, che
può compiere un controllo di questo tipo al momento dell'esecuzione.
In genere, bisognerebbe evitare di specificare VERSIONE come un valore testuale nella
forma v5.6.1, poiché ciò causa, sotto versioni vecchie del Perl che non
supportano questa sintassi, dei messaggi di errore fuorvianti. Al suo posto dovrebbe
essere usata la versione numerica.
use v5.6.1; # controllo di versione al momento della compilazione
use 5.6.1; # uguale
use 5.006_001; # uguale; preferibile per compatibilita` all'indietro
Questo è spesso utile se avete bisogno di controllare la versione di Perl
corrente prima prima di chiamare use per usare dei moduli di libreria che avere
modificato in maniera incompatibile con le versioni più vecchie di Perl.
(Cerchiamo di non fare questo più di quanto siamo costretti).
Il blocco BEGIN forza require ed import ad essere eseguiti al momento della
compilazione. L'istruzione require assicura che il modulo venga caricato in memoria,
se non lo è già. L'istruzione import non è integrata in
Perl--è semplicemente una normale chiamata ad un metodo statico all'interno del
package Module , allo scopo di dire al modulo di importare la lista di caratteristiche
nel package corrente. Il modulo può implementare il suo metodo import come
desidera, anche se la maggior parte dei moduli decidono semplicemente di derivarlo,
utilizzando l'ereditarietà, dalla classe Exporter definita nel modulo
Exporter . Consultate Exporter. Se non si riesce a trovare alcun metodo import ,
la chiamata viene saltata.
Se non volete chiamare il metodo import del package (per esempio allo scopo di evitare
l'alterazione del vostro spazio dei nomi), fornite esplicitamente una lista vuota:
use Modulo ();
Questo equivale esattamente a
BEGIN { require Modulo }
Se tra Modulo e LISTA è presente l'argomento VERSIONE, allora use
chiamerà il metodo VERSIONE nella classe Modulo passandogli come argomento la
versione indicata. Il metodo di default VERSIONE, ereditato dalla classe UNIVERSAL, muore
se la versione indicata è maggior del valore della variabile $Modulo::VERSIONE .
Inoltre, c'è una distinzione tra omettere LISTA (import chiamata senza
argomenti) ed un'esplicita LISTA vuota () (import non è chiamata). Va
notato che non c'è alcuna virgola dopo VERSIONE!
Siccome questa interfaccia è molto aperta, i pragma (direttive del compilatore)
sono anch'essi implementati in questo modo. Le direttive implementate al momento sono:
use constant;
use diagnostics;
use integer;
use sigtrap qw(SEGV BUS);
use strict qw(subs vars refs);
use subs qw(afunc blurfl);
use warnings qw(all);
use sort qw(stable _quicksort _mergesort);
Alcuni di questi pseudomoduli importano le semantiche nel corrente blocco dello scope
(ad esempio strict o integer , a differenza dei moduli ordinari che importano
simboli nel package corrente (che hanno effetti fino alla fine del file)).
C'è un corrispondente comando no che annulla l'importazione di quanto
importate da use , cioè chiama unimport Modulo LISTA anziché
import .
no integer;
no strict 'refs';
no warnings;
Consultate perlmodlib per una lista di moduli e di direttive standard. Consultate
perlrun per le opzioni da linea di comando -M e -m , che rendono accessibili le
funzionalità di use dalla linea di comando.
(*) 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]
- utime LISTA
-
Cambia i tempi di accesso e di modifica su ogni file di una lista di file. I primi due
elementi della lista devono essere i tempi NUMERICI di accesso e modifica, in
quest'ordine. Restituisce il numero di file modificati con successo. Il tempo di modifica
dell'inode di ogni file viene impostato all'istante corrente. Per esempio, questo codice
ha lo stesso effetto del comando Unix
touch(1) se il file esiste già ed appartiene
all'utente che sta eseguendo il programma:
#!/usr/bin/perl
$tempoa = $tempom = time;
utime $tempoa, $tempom, @ARGV;
A partire dal perl 5.7.2, se i primi due elementi della lista sono undef , allora la
funzione utime(2) nella libreria C verrà chiamata con un secondo argomento null.
Sulla maggior parte dei sistemi, questo imposterà i tempi di accesso e modifica
del file all'istante corrente (equivalente cioè al suddetto esempio) e funzionerà
anche sui file di altri utenti dove avrete i permessi di scrittura:
utime undef, undef, @ARGV;
Con NFS userà la data del server NFS, non la data della macchina locale.
Se sussiste un problema di sincronizzazione, allora il server NFS e la macchina locale avranno
date diverse. Il comando Unix touch in effetti userà questa forma anziché
quella mostrata nel primo esempio.
Va notato che solo passare uno dei primi due elementi come undef risulterà equivalente
al passarlo come 0, e non avrà lo stesso effetto descritto quando essi sono entrambi
undef. In questo caso verrà fatto scattare un avvertimento per il valore indefinito.
- values HASH
-
Restituisce una lista contenente tutti i valori dell'hash passato come parametro.
(In contesto scalare, restituisce il numero di valori).
I valori sono restituiti in un ordine apparentemente casuale. Tale ordine casuale
sarà soggetto a cambiamenti nelle future versioni di perl, ma è garantito
essere lo stesso ordine che producono le funzioni keys e each sullo stesso
(non modificato) hash. Per ragioni di sicurezza, a partire dal Perl 5.8.1 l'ordinamento
è differente anche tra diverse esecuzioni di Perl (consultate
perlsec/``Algorithmic Complexity Attacks'' [``Attacchi di Complessità Algoritmica'', NdT]).
Come effetto collaterale, la chiamata a values() reimposta l'iteratore interno dell'HASH,
si veda each. (In particolare, una chiamata a values() in un contesto vuoto, reimposta
l'iteratore senza alcun costo computazionale aggiuntivo).
Va notato che i valori non vengono copiati, il che significa che
modificare essi modifica i contenuti dell'hash:
for (values %hash) { s/pippo/pluto/g } # modifica i valori di %hash
for (@hash{keys %hash}) { s/pippo/pluto/g } # stessa cosa
Consultate anche keys , each e sort .
- vec ESPR,SCOSTAMENTO,NUMERO_DI_BIT
-
Tratta la stringa in ESPR come un vettore di bit confezionato con elementi di ampiezza
NUMERO_DI_BIT e restituisce il valore dell'elemento specificato da OFFSET come intero
senza segno. NUMERO_DI_BIT dunque specifica il numero di bit che sono riservati per ogni
elemento nel vettore di bit. Questo deve essere una potenza di due da 1 a 32 (oppure 64
se la piattaforma li supporta).
Se NUMERO_DI_BIT è 8, ``elementi'' coincide con i byte della stringa di input.
Se NUMERO_DI_BIT è 16 o più, i byte della stringa di input sono
raggruppati in pezzi di dimensione NUMERO_DI_BIT/8 ed ogni gruppo viene convertito in un
numero come con pack()/unpack() con i formati big-endian n /N (analogamente per
NUMERO_DI_BIT==64). Consultate pack per i dettagli.
Se il numero di bit è 4 o meno, la stringa viene spezzata in bytes, poi i bit di
ogni byte sono spezzati in 8/NUMERO_DI_BIT gruppi. I bit di un byte sono numerati alla
maniere dei little-endian, come in 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 ,
0x40 , 0x80 . Per esempio, spezzare il singolo byte di input chr(0x36) in due
gruppi, dà una lista (0x6, 0x3) ; spezzarlo in 4 gruppi dà
(0x2, 0x1, 0x3, 0x0) .
vec può anche essere assegnato, nel qual caso le parentesi sono necessarie per
dare all'espressione la corretta precedenza, come in
vec($immagine, $max_x * $x + $y, 8) = 3;
Se l'elemento selezionato è al di fuori della stringa, viene restituito il valore
0. Se un elemento viene scritto oltre la fine della stringa, il Perl per prima cosa
estenderà la stringa con un numero adeguato di byte a zero. È un errore il
tentare di scrivere oltre l'inizio della stringa (cioè uno SCOSTAMENTO negativo).
La stringa non dovrebbe contenere alcun carattere con valore > 255 (che può
avvenire solo se si sta usando la codifica UTF8). Se lo contiene, sarà trattato
come qualcosa che non è codificata UTF8. Quando vec viene assegnato, anche
altre parti del programma non considereranno la stringa come codificata UTF8. In altre
parole, se si hanno tali caratteri nelle stringhe, vec() opererà sulla stringa di
byte effettiva e non sulla stringa di caratteri concettuale.
Le stringhe create con vec possono anche venir manipolate con gli operatori logici
| , & , ^ e ~ . Questi operatori assumeranno che quando entrambi gli operandi
sono stringhe, sarà richiesta un'operazione a vettore di bit. Si veda
perlop/``Bitwise String Operators'' [``Operatori di stringa bitwise'', NdT].
Il codice seguente costruirà una stringa ASCII che recita 'PerlPerlPerl' .
I commenti mostrano la stringa dopo ogni passo. Va notato che questo codice funziona nella
stessa maniera sia su elaboratori big-endian che little-endian.
my $pippo = '';
vec($pippo, 0, 32) = 0x5065726C; # 'Perl'
# $pippo eq "Perl" eq "\x50\x65\x72\x6C", 32 bit
print vec($pippo, 0, 8); # stampa 80 == 0x50 == ord('P')
vec($pippo, 2, 16) = 0x5065; # 'PerlPe'
vec($pippo, 3, 16) = 0x726C; # 'PerlPerl'
vec($pippo, 8, 8) = 0x50; # 'PerlPerlP'
vec($pippo, 9, 8) = 0x65; # 'PerlPerlPe'
vec($pippo, 20, 4) = 2; # 'PerlPerlPe' . "\x02"
vec($pippo, 21, 4) = 7; # 'PerlPerlPer'
# 'r' e` "\x72"
vec($pippo, 45, 2) = 3; # 'PerlPerlPer' . "\x0c"
vec($pippo, 93, 1) = 1; # 'PerlPerlPer' . "\x2c"
vec($pippo, 94, 1) = 1; # 'PerlPerlPerl'
# 'l' e` "\x6c"
Per trasformare un vettore di bit in una stringa o lista di 0 e 1, si usino queste:
$numero_di_bit = unpack("b*", $vettore);
@numero_di_bit = split(//, unpack("b*", $vettore));
Se siete a conoscenza dell'esatta lunghezza in bit, la si può usare al posto del
* .
Ecco un esempio per illustrare come i bit vanno effettivamente a posto:
#!/usr/bin/perl -wl
print <<'EOT';
0 1 2 3
unpack("V",$_) 01234567890123456789012345678901
------------------------------------------------------------------
EOT
for $w (0..3) {
$ampiezza = 2**$w;
for ($spostamento=0; $spostamento < $ampiezza; ++$spostamento) {
for ($distanza=0; $distanza < 32/$ampiezza; ++$distanza) {
$str = pack("B*", "0"x32);
$numero_di_bit = (1<<$spostamento);
vec($str, $distanza, $ampiezza) = $numero_di_bit;
$ris = unpack("b*",$str);
$val = unpack("V", $str);
write;
}
}
}
format STDOUT =
vec($_,@#,@#) = @<< == @######### @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$distanza, $ampiezza, $numero_di_bit, $val, $ris
.
__END__
Indifferente all'architettura dell'elaboratore sul quale viene eseguito, l'esempio
soprastante dovrebbe stampare la seguente tabella:
0 1 2 3
unpack("V",$_) 01234567890123456789012345678901
------------------------------------------------------------------
vec($_, 0, 1) = 1 == 1 10000000000000000000000000000000
vec($_, 1, 1) = 1 == 2 01000000000000000000000000000000
vec($_, 2, 1) = 1 == 4 00100000000000000000000000000000
vec($_, 3, 1) = 1 == 8 00010000000000000000000000000000
vec($_, 4, 1) = 1 == 16 00001000000000000000000000000000
vec($_, 5, 1) = 1 == 32 00000100000000000000000000000000
vec($_, 6, 1) = 1 == 64 00000010000000000000000000000000
vec($_, 7, 1) = 1 == 128 00000001000000000000000000000000
vec($_, 8, 1) = 1 == 256 00000000100000000000000000000000
vec($_, 9, 1) = 1 == 512 00000000010000000000000000000000
vec($_,10, 1) = 1 == 1024 00000000001000000000000000000000
vec($_,11, 1) = 1 == 2048 00000000000100000000000000000000
vec($_,12, 1) = 1 == 4096 00000000000010000000000000000000
vec($_,13, 1) = 1 == 8192 00000000000001000000000000000000
vec($_,14, 1) = 1 == 16384 00000000000000100000000000000000
vec($_,15, 1) = 1 == 32768 00000000000000010000000000000000
vec($_,16, 1) = 1 == 65536 00000000000000001000000000000000
vec($_,17, 1) = 1 == 131072 00000000000000000100000000000000
vec($_,18, 1) = 1 == 262144 00000000000000000010000000000000
vec($_,19, 1) = 1 == 524288 00000000000000000001000000000000
vec($_,20, 1) = 1 == 1048576 00000000000000000000100000000000
vec($_,21, 1) = 1 == 2097152 00000000000000000000010000000000
vec($_,22, 1) = 1 == 4194304 00000000000000000000001000000000
vec($_,23, 1) = 1 == 8388608 00000000000000000000000100000000
vec($_,24, 1) = 1 == 16777216 00000000000000000000000010000000
vec($_,25, 1) = 1 == 33554432 00000000000000000000000001000000
vec($_,26, 1) = 1 == 67108864 00000000000000000000000000100000
vec($_,27, 1) = 1 == 134217728 00000000000000000000000000010000
vec($_,28, 1) = 1 == 268435456 00000000000000000000000000001000
vec($_,29, 1) = 1 == 536870912 00000000000000000000000000000100
vec($_,30, 1) = 1 == 1073741824 00000000000000000000000000000010
vec($_,31, 1) = 1 == 2147483648 00000000000000000000000000000001
vec($_, 0, 2) = 1 == 1 10000000000000000000000000000000
vec($_, 1, 2) = 1 == 4 00100000000000000000000000000000
vec($_, 2, 2) = 1 == 16 00001000000000000000000000000000
vec($_, 3, 2) = 1 == 64 00000010000000000000000000000000
vec($_, 4, 2) = 1 == 256 00000000100000000000000000000000
vec($_, 5, 2) = 1 == 1024 00000000001000000000000000000000
vec($_, 6, 2) = 1 == 4096 00000000000010000000000000000000
vec($_, 7, 2) = 1 == 16384 00000000000000100000000000000000
vec($_, 8, 2) = 1 == 65536 00000000000000001000000000000000
vec($_, 9, 2) = 1 == 262144 00000000000000000010000000000000
vec($_,10, 2) = 1 == 1048576 00000000000000000000100000000000
vec($_,11, 2) = 1 == 4194304 00000000000000000000001000000000
vec($_,12, 2) = 1 == 16777216 00000000000000000000000010000000
vec($_,13, 2) = 1 == 67108864 00000000000000000000000000100000
vec($_,14, 2) = 1 == 268435456 00000000000000000000000000001000
vec($_,15, 2) = 1 == 1073741824 00000000000000000000000000000010
vec($_, 0, 2) = 2 == 2 01000000000000000000000000000000
vec($_, 1, 2) = 2 == 8 00010000000000000000000000000000
vec($_, 2, 2) = 2 == 32 00000100000000000000000000000000
vec($_, 3, 2) = 2 == 128 00000001000000000000000000000000
vec($_, 4, 2) = 2 == 512 00000000010000000000000000000000
vec($_, 5, 2) = 2 == 2048 00000000000100000000000000000000
vec($_, 6, 2) = 2 == 8192 00000000000001000000000000000000
vec($_, 7, 2) = 2 == 32768 00000000000000010000000000000000
vec($_, 8, 2) = 2 == 131072 00000000000000000100000000000000
vec($_, 9, 2) = 2 == 524288 00000000000000000001000000000000
vec($_,10, 2) = 2 == 2097152 00000000000000000000010000000000
vec($_,11, 2) = 2 == 8388608 00000000000000000000000100000000
vec($_,12, 2) = 2 == 33554432 00000000000000000000000001000000
vec($_,13, 2) = 2 == 134217728 00000000000000000000000000010000
vec($_,14, 2) = 2 == 536870912 00000000000000000000000000000100
vec($_,15, 2) = 2 == 2147483648 00000000000000000000000000000001
vec($_, 0, 4) = 1 == 1 10000000000000000000000000000000
vec($_, 1, 4) = 1 == 16 00001000000000000000000000000000
vec($_, 2, 4) = 1 == 256 00000000100000000000000000000000
vec($_, 3, 4) = 1 == 4096 00000000000010000000000000000000
vec($_, 4, 4) = 1 == 65536 00000000000000001000000000000000
vec($_, 5, 4) = 1 == 1048576 00000000000000000000100000000000
vec($_, 6, 4) = 1 == 16777216 00000000000000000000000010000000
vec($_, 7, 4) = 1 == 268435456 00000000000000000000000000001000
vec($_, 0, 4) = 2 == 2 01000000000000000000000000000000
vec($_, 1, 4) = 2 == 32 00000100000000000000000000000000
vec($_, 2, 4) = 2 == 512 00000000010000000000000000000000
vec($_, 3, 4) = 2 == 8192 00000000000001000000000000000000
vec($_, 4, 4) = 2 == 131072 00000000000000000100000000000000
vec($_, 5, 4) = 2 == 2097152 00000000000000000000010000000000
vec($_, 6, 4) = 2 == 33554432 00000000000000000000000001000000
vec($_, 7, 4) = 2 == 536870912 00000000000000000000000000000100
vec($_, 0, 4) = 4 == 4 00100000000000000000000000000000
vec($_, 1, 4) = 4 == 64 00000010000000000000000000000000
vec($_, 2, 4) = 4 == 1024 00000000001000000000000000000000
vec($_, 3, 4) = 4 == 16384 00000000000000100000000000000000
vec($_, 4, 4) = 4 == 262144 00000000000000000010000000000000
vec($_, 5, 4) = 4 == 4194304 00000000000000000000001000000000
vec($_, 6, 4) = 4 == 67108864 00000000000000000000000000100000
vec($_, 7, 4) = 4 == 1073741824 00000000000000000000000000000010
vec($_, 0, 4) = 8 == 8 00010000000000000000000000000000
vec($_, 1, 4) = 8 == 128 00000001000000000000000000000000
vec($_, 2, 4) = 8 == 2048 00000000000100000000000000000000
vec($_, 3, 4) = 8 == 32768 00000000000000010000000000000000
vec($_, 4, 4) = 8 == 524288 00000000000000000001000000000000
vec($_, 5, 4) = 8 == 8388608 00000000000000000000000100000000
vec($_, 6, 4) = 8 == 134217728 00000000000000000000000000010000
vec($_, 7, 4) = 8 == 2147483648 00000000000000000000000000000001
vec($_, 0, 8) = 1 == 1 10000000000000000000000000000000
vec($_, 1, 8) = 1 == 256 00000000100000000000000000000000
vec($_, 2, 8) = 1 == 65536 00000000000000001000000000000000
vec($_, 3, 8) = 1 == 16777216 00000000000000000000000010000000
vec($_, 0, 8) = 2 == 2 01000000000000000000000000000000
vec($_, 1, 8) = 2 == 512 00000000010000000000000000000000
vec($_, 2, 8) = 2 == 131072 00000000000000000100000000000000
vec($_, 3, 8) = 2 == 33554432 00000000000000000000000001000000
vec($_, 0, 8) = 4 == 4 00100000000000000000000000000000
vec($_, 1, 8) = 4 == 1024 00000000001000000000000000000000
vec($_, 2, 8) = 4 == 262144 00000000000000000010000000000000
vec($_, 3, 8) = 4 == 67108864 00000000000000000000000000100000
vec($_, 0, 8) = 8 == 8 00010000000000000000000000000000
vec($_, 1, 8) = 8 == 2048 00000000000100000000000000000000
vec($_, 2, 8) = 8 == 524288 00000000000000000001000000000000
vec($_, 3, 8) = 8 == 134217728 00000000000000000000000000010000
vec($_, 0, 8) = 16 == 16 00001000000000000000000000000000
vec($_, 1, 8) = 16 == 4096 00000000000010000000000000000000
vec($_, 2, 8) = 16 == 1048576 00000000000000000000100000000000
vec($_, 3, 8) = 16 == 268435456 00000000000000000000000000001000
vec($_, 0, 8) = 32 == 32 00000100000000000000000000000000
vec($_, 1, 8) = 32 == 8192 00000000000001000000000000000000
vec($_, 2, 8) = 32 == 2097152 00000000000000000000010000000000
vec($_, 3, 8) = 32 == 536870912 00000000000000000000000000000100
vec($_, 0, 8) = 64 == 64 00000010000000000000000000000000
vec($_, 1, 8) = 64 == 16384 00000000000000100000000000000000
vec($_, 2, 8) = 64 == 4194304 00000000000000000000001000000000
vec($_, 3, 8) = 64 == 1073741824 00000000000000000000000000000010
vec($_, 0, 8) = 128 == 128 00000001000000000000000000000000
vec($_, 1, 8) = 128 == 32768 00000000000000010000000000000000
vec($_, 2, 8) = 128 == 8388608 00000000000000000000000100000000
vec($_, 3, 8) = 128 == 2147483648 00000000000000000000000000000001
- wait
-
Si comporta come la chiamata di sistema
wait(2) presente sul vostro sistema: aspetta che
un processo figlio termini e restituisce il pid del processo terminato oppure -1 se
non ci sono processi figli. Lo stato viene restituito in $? . Va notato che un valore
restituito pari a -1 potrebbe significare che i processi figli sono stati raccolti
automaticamente, come descritto in perlipc.
- waitpid PID,FLAG
-
Attende che un particolare processo figlio abbia terminato e restituisce il pid del
processo deceduto oppure
-1 se tale processo non esiste. Su alcuni sistemi, un valore
0 indica che ci sono processi ancora in esecuzione. Lo stato viene restituito in $? .
Se si afferma
use POSIX ":sys_wait_h";
#...
do {
$figlio = waitpid(-1, WNOHANG);
} until $figlio > 0;
poi è possibile eseguire un wait non bloccante per tutti i processi zombie
pendenti. Il wait non bloccante è disponibile su elaboratori che supportano sia
la chiamata di sistema waitpid(2) che quella wait4(2). Comunque, l'attendere per un
particolare pid con FLAG di 0 è implementato ovunque. (Il Perl emula la
chiamata di sistema ricordando i valori dello stato dei processi che sono usciti ma che
non sono stati ancora raccolti dallo script Perl).
Va notato che su alcuni sistemi, un valore restituito pari a -1 potrebbe significare che i
processi figli sono stati automaticamente raccolti. Consultate perlipc per i dettagli e
per altri esempi.
- wantarray
-
Restituisce vero se il contesto della subroutine attualmente in esecuzione o
eval
si aspetta un valore di lista. Restituisce falso se il contesto si aspetta uno scalare.
Restituisce un valore indefinito se il contesto non si aspetta alcun valore (contesto
vuoto).
return unless defined wantarray; # non si disturbi facendo altro
my @a = calcolo_complesso();
return wantarray ? @a : "@a";
Il risultato di wantarray() è non specificato nello scope di livello
più esterno di un file, in un blocco BEGIN , CHECK , INIT o END oppure in un metodo
DESTROY .
Piuttosto, questa funzione si sarebbe dovuta chiamare wantlist()
[``wantarray''=``voglio un array'' mentre ``wantlist''=``voglio una lista'', NdT].
- warn LISTA
-
Genera un messaggio sullo STDERR, esattamente come c<die>, ma non esce e non solleva
un'eccezione.
Se LISTA è vuota e $@ contiene già un valore (solitamente derivante da
un precedente eval), tale valore viene utilizzato dopo aver concatenato "\t...caught" [preso, NdT]
a $@ . Questo è utile per rimanere quasi, ma non del tutto, uguali a die .
Se $@ è vuota, allora viene utilizzata la stringa
"Warning: Something's wrong" [``Attenzione: Qualcosa è andato storto'', NdT].
Se è stato installato un handler di $SIG{__WARN__} , non viene visualizzato
alcun messaggio. È compito dell'handler occuparsi del messaggio nella maniera che
ritiene opportuna (ad esempio, convertendolo in una die ). La maggior parte degli
handler devono quindi occuparsi di visualizzare i warning che non sono preparati a
gestire, chiamando warn di nuovo all'interno dell'handler stesso. Va notato che questa
è una procedure sicura, che non creerà un ciclo senza fine,
poiché gli hook a __WARN__ non vengono chiamati dall'interno di uno di essi.
Noterete che questo comportamento è in qualche modo diverso da quello degli
handler di $SIG{__DIE__} (che non sopprimono il testo di errore, ma possono invece
chiamare di nuovo die per cambiarli).
L'uso dell'handler __WARN__ fornisce un potente metodo per mettere a tacere tutti i
warning (anche quelli cosiddetti obbligatori). Ad esempio:
# cancella *tutti* i warning della compilazione
BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $FAIWARN } }
my $pippo = 10;
my $pippo = 20; # nessun warning sul my $pippo duplicato,
# ma ehi, lo avete chiesto voi!
# nessun warning di compilazione o esecuzione prima di questo punto
$FAIWARN = 1;
# warning di esecuzione abilitati dopo questo punto
warn "\$pippo e` vivo e $pippo!"; # viene mostrato
Consultate perlvar per dettagli sull'impostazione delle voci in %SIG , e per altri
esempi. Consultate il modulo Carp per altri tipi di warning che usano le sue funzioni
carp() e cluck().
- write FILEHANDLE
-
- write ESPR
-
- write
-
Scrive un record formattato (possibilmente multi linea) al FILEHANDLE specificato, usando il
formato associato con quel file. Il formato di default per un file è quello avente lo
stesso nome del filehandle, ma il formato per il canale di output corrente (si veda la funzione
select ) potrebbe essere impostato esplicitamente assegnando il nome del formato alla
variabile $~ .
L'elaborazione della parte superiore del modulo viene trattata automaticamente: se c'è
uno spazio insufficiente sulla pagina corrente per il record formattato, la pagina viene
avanzata scrivendo un form feed [avanzamento modulo, NdT], per formattare l'intestazione della
nuova pagina viene usato uno speciale formato sommità-della-pagina, poi il record viene
scritto. Di default, il formato sommità-della-pagina è il nome del filehandle a
cui è aggiunto ``_TOP'' [sommità, NdT], ma può essere dinamicamente
impostato al formato di propria scelta assegnando il nome alla variabile $^ mentre il
filehandle viene selezionato. Il numero di linee rimanenti sulla pagina corrente si trova nella
variabile $- , la quale può essere impostata a 0 per forzare una nuova pagina.
Se FILEHANLDE non è specificato, l'output va sul canale di output di default corrente,
il quale comincia come STDOUT ma può essere cambiato dall'operatore select . Se il
FILEHANDLE è una ESPR, allora l'espressione viene valutata e la stringa risultante
viene usata per cercare il nome del FILEHANDLE a tempo di esecuzione. Per dell'altro sui
formati, si veda perlform.
Va notato che write non è l'opposto di read . Sfortunatamente.
- y///
-
L'operatore di traslitterazione. Lo stesso che
tr/// . Consultate perlop.
La versione su cui si basa questa traduzione è ottenibile con:
perl -MPOD2::IT -e print_pod perlfunc
Per maggiori informazioni sul progetto di traduzione in italiano si veda
http://pod2it.sourceforge.net/ .
Traduzione a cura di dree e molti altri.
Revisione a cura di dree.
Mon Jun 11 22:02:16 2012
|