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. Gli elementi di LISTA dovrebbero essere
separati da virgole.
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,
getprgp, 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]) }
- 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 condifica 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ò singnifica 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 la funzione che effettua il bless
potrebbe essere ereditta da una classe derivata. 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
dunque, 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 valor 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
- 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.
- 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
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 è interpreato 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;
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
- 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
- Cifra una stringa esattamente come fa la funzione
crypt(3)
della libreria C (assumendo che abbiate a disposizione una versione di
quest'ultima che non sia stata privata di tale funzione per questioni di
sicurezza). Questa funzione può risultare utile, tra le altre cose, per
cercare password poco sicure nei file delle password. Solo i ragazzi con
il cappello bianco dovrebbero cimentarsi con crypt().
Va notato che crypt
è intesa come una funzione a senso unico, un po' come il rompere le uova
per fare la frittata. Non c'è (tra quelle conosciute) nessuna funzione
decrypt (in altre parole, crypt()
è una funzione hash a senso unico). A causa di ciò, queata funzione non
è molto utile per la crittografia. (Per quest'ultima, consultate il
vostro mirror CPAN più vicino).
Quando effetuate la verifica di una stringa cifrata dovete usare il
testo cifrato come seme (ad esempio crypt($chiaro,
$cifrato) eq $cifrato). 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 nella stringa cifrata.
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
cifrata 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 cifrare grandi quantità di dati, non del tutto almeno,
perché non potete ottenere le vostre informazioni di nuovo in chiaro.
Date un'occhiata alle directory by-module/Crypt e a
by-module/PGP sul vostro mirror CPAN preferito per un mucchio
di moduli potenzialmente utili.
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 settare 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''. Ma 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. Va notato che cancellare
elementi nel mezzo di un array non farà scorrere in basso l'indice degli
elementi successivi, per quello usate splice(). Consultate 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 cose: 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 $@. Un esempio:
eval { ... ; die Unqualche::Modulo::Eccezione->new( PIPPO => "pluto" ) };
if ($@) {
if (ref($@) && UNIVERSAL::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à sia stata
pensata per essere eseguita solo appena prima dell'uscita dal programma,
attualmente non è 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, 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)
- Una forma deprecata di chiamata di subroutine. 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 proramma. 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 inzializzato tutte
le vostre variabili all'inizio del programma. Quando il nuovo binario
viene eseguito, inzierà 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
file-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'utimo 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
- 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 blocanti, è 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 $@
A causa del corrente, opinabilmente non corretto, stato degli hook di
__DIE__, quando si usa la forma eval{}
come una trappola per le eccezioni nelle librerie, si potrebbe non voler
innescare alcun hook per __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__ pssono 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 accadendno (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, potete invece
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 l'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 arogmento
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 subrotuine,
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
- 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 definzioni 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: $!";
No 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 dei
file sottoposti a lock con flock
possono essere modificati da quei programmi che non usano 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 indivudualmente 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'efficienze è 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;
Si veda 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,
ma 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 inzio 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 effetturare 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 interfaccie 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, globa() 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
utilizzato l'estensione standard File::Glob. Consultate the File::Glob
manpage per i dettagli.
- gmtime ESPR
- 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).
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 non volete
fare ciò, 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
- 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,SUBSTR,POSIZIONE
-
- index STR,SUBSTR
- 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 regular expression. Essa restituisce
la posizione della prima occorrenza di SUBSTR in STR, a partire da
POSIZIONE. Se POSIZIONE viene omessa,
index()
inizia a cercare dall'inizio della stringa. Il valore restituito indica
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 "ioctl.ph"; # probabilmente in /usr/local/lib/perl/ioctl.ph
per ottenere le corrette definizioni delle funzioni. Se
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 l'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 il settare 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 impacchettament 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 inziare 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 ingnorato in tuti e tre i
casi). Il seguente codice è in grado di gestire decimali, binari, ottali
ed esacimali 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 èegue 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 processatti
(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 tre 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 version 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: $!"; # in memory files
open(MEMORY,'>', \$var)
or die "Impossibile aprire il file in memoria: $!";
print MEMORY "foo!\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 tre 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
semplicemente utilizzate 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) putete 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
settare $| ($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 nomifle 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 possibilita 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 autimaticamente.
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
dichiara le variabili indicate come globali valide, nel blocco che le
include, file, o eval.
Ciò significa che le regole di scoping sono le stesse della
dichiarazione ``my'', ma non viene creata una variabile locale. Se è
indicato più di un valore, la lista deve essere inclusa tra parentesi.
La dichiarazione our
non ha alcun effetto semantico a meno che non sia attivo ``use strict
vars'', nel qual caso essa consente di utilizzare la variabile globale
dichiarata senza qualificarla con un nome di package. (Ma solo
all'interno dello scope lessicale della dichiarazione our.
In questo essa differisce da ``use vars'', il cui scope è a livello di
package).
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
Sono permesse multiple dichiarazioni our
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. 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
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 tesuale (ASCII), sara` completata da spazi.
Z Una stringa terminata da null (ASCIZ), sara` completata da null.
b Una stringa di bit (ordine ascendente dei bit all'interno di ciascun bye, come vec()).
B Una stringa di bit (ordine discendente dei bit all'interno di ciascun bye).
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 segnp (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 sengo (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, and 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 ingorati.
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 corrispondentente
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 ingorata. 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 catteri "\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 and
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 lon).
- 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 locali. 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
apparterrano 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
prefissandoli con 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 settare
$| 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,
mentre 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 cusa 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 chisura,
inserite un + o mettere parentesi attorno a tutti gli
argomenti.
Va notato che, se i FILEHANDLE che utilizzate sono contenuti in un
array o in un'altra espressione, dovrete utilizzare un blocco che ne
restituisca il valore: 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 nuovo numero di elementi
nell'array.
- 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 signfica che tutti i caratteri che
non rientrano in
/[A-Za-z_0-9]/ saranno preceduti da un
backslash nella stringa restituita, indipendentemente da qualsiasi
settaggio 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 a prependere 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. Questo comando viene
usato di norma da quei programmi che voglio ingannare loro stessi a
proposito dell'input: # 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";
}
if (UNIVERSAL::isa($r, "HASH")) { # per le subclassi
print "r e` un riferimento a qualcosa che e` un (isa) hash.\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 sistem 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
``Foo/Bar.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 @NIC 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 soubroutine 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]
(**) letterlamente aggancio, questo termine indica la procedura di
codificare un programma che permetta all'utente di espenderlo. Ad
esempio il funzionamento dei plugin di <programma con plugin> è
permesso grazie a degli hook.
(***) letteralmente santificato, consacrato, si intende di un oggetto
che è stato legato al nome di un package. Si veda la funzione bless.
- 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,SUBSTR,POSIZIONE
-
- rindex STR,SUBSTR
- Funziona come index(), solo che restituisce la posizione dell'ULTIMA
occorrenza di SUBSTR in STR. Se viene specificata una POSIZIONE,
restituisce l'ultima occorrenza 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 directiry, 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.
Note: on some Unixes, the select(2)
system call may report a socket file descriptor as ``ready for
reading'', when actually no data is available, thus a subsequent read
blocks. It can be avoided using always the O_NONBLOCK flag on the
socket. See select(2)
and fcntl(2)
for further details.
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 definzioni 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). Il numero di operazioni sui
semafori è implicitamente fornito dalla lunghezza di STRINGAOPZ.
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'' [``UPD: 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 pmessi, 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. VALOREOPZ può essere specificato
come
undef
se non desiderate passare un argomento.
- 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 definzioni 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 verrano scritti per rimepire 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 chiamama 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
modificateli.
Inoltre, non potte 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.
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($len,@foo[1..$len],0+@bar,@bar)) { ... }
- 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 LIMIT 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''
- Il flag ``vettore''
v, opzionalmente la stringa da
utilizzare per unire i valori. Questo flag dice al perl di
interpretare la stringa fornita come un vettore di interi, uno per
ogni carattere nella stringa, separati da una stringa (un punto
. per default). Può essere utile per stampare i valori
ordinali dei caratteri in una stringa arbitraria: 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 indifca 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 EXPR
-
- srand
- Imposta il seme del generatore di numeri casuali per l'operatore
rand.
Lo scopo della funzione è seminare [``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.
Va notato che vi serve qualcosa di più casuale del seme di default
per usi inerenti la crittografia. 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 modalitE<agrave> 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<egrave> 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 succcesso, 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 "File is %s, size is %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 = $mode & 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, eseczuione, 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_ISCHR 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 foo\n" if /\bfoo\b/;
print ".IX bar\n" if /\bbar\b/;
print ".IX blurfl\n" if /\bblurfl\b/;
# ...
print;
}
Cercando /\bfoo\b, verranno controllati solo le
posizioni in $_ che contengono f, 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 valutar 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().
Se il valore assegnabile restituito da substr viene usato dopo che la
ESPR è stata cambiata in un qualche modo, il comportamento potrebbe non
essere quello atteso ed è soggetto a cambiamenti. Questo avvertimento
comprende codice come print(substr($pippo,$a,$b)=$pluto)
oppure (substr($pippo,$a,$b)=$pluto)=$paperino
(dove $pippo viene cambiato tramite l'assegnazione della sottostringa, e
poi subst viene utilizzato di nuovo), o dove viene creato un alias di
una substr()
tramite un ciclo foreach, oppure viene passata come
parametro, oppure viene preso un riferimento ad essa e poi l'alias, il
parametro, oppure il riferimento dereferenziato viene utilizzato dopo
che l'ESPR originale è stato cambiato, oppure viene assegnato e poi
utilizzato un seconda volta.
- 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 LISTA
- Invoca la chiamata di sistema specificata come primo elemento della
lsta, 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
fallice, syscall
restituisce -1 ed imposta $! (errno). Va
notato che alcune chiamate di sistema possono legittimamente restituire
-1. La maniera approrpiata 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 (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 FIELHANDLE 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. 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
- Setta 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 subrotuine
(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 cancellerà le directory a meno che non siate superuser e non venga
bassato il flag -U al Perl. Anche se queste condizioni
risultano soddisfatte, sappiate che effettuare un unlink su una
directory poè danneggiare seriamente il vostro filesystem. 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 quest'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às oggetto 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); # prints 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 striga 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
zombi 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 ritene 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 settata 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.
Mon Oct 24 04:01:53 2005 |