![]() |
| index | project | pods | responsabili |
NOMEperldata - Tipi di dato in Perl
DESCRIZIONE
Nomi di variabilePerl ha tre tipi di dati incorporati: scalari, array di scalari e array associativi di scalari, meglio noti come ``hash''. Uno scalare può essere costituito da una singola stringa (di qualsiasi dimensione, limitata solo dalla memoria a disposizione), da un numero o da un riferimento a qualcosa (il che viene discusso in perlref). I normali array sono liste ordinate di scalari indicizzate con un numero intero, partendo da 0. Le hash sono collezioni non ordinate di valori scalari indicizzate attraverso una stringa associata ad essi, detta chiave. Di solito ci si riferisce ai valori o per nome, o attraverso un
riferimento con nome. Il primo carattere del nome vi dice a che tipo
di struttura dati si riferisce; il resto del nome indica il particolare
valore. Di solito questo nome è un singolo identificatore, ossia
una stringa che comincia con una lettera o un underscore [il trattino
messo in basso ``_'', N.d.T.], e prosegue con lettere, underscore e
cifre numeriche. In alcuni casi potrebbe essere una concatenazione di
identificatori, separati da Perl ha anche le sue variabili incorporate i cui nomi non seguono
queste regole. Queste variabili hanno nomi strani, per cui non c'è il
rischio che vadano accidentalmente a collidere con una delle vostre
variabili. Le stringhe che corrispondono alle parti fra parentesi di
un'espressione regolare sono salvate con nomi che contengono solo
cifre numeriche dopo il carattere I valori scalari hanno sempre nomi con
$giorni # Il semplice valore scalare "giorni"
$giorni[28] # Il ventinovesimo elemento dell'array @giorni
$giorni{'Feb'} # Il valore 'Feb' dall'hash %giorni
$#giorni # L'ultimo indice dell'array @giorni
Interi array (e slice [porzioni, N.d.T.] di array ed hash) sono
indicati con
@giorni # ($giorni[0], $giorni[1], ..., $giorni[n])
@giorni[3, 4, 5] # corrisponde a ($giorni[3], $giorni[4], $giorni[5])
@giorni{'a', 'c'} # corrisponde a ($giorni{'a'}, $giorni{'c'})
Le hash intere sono denotate da
%giorni # ($chiave1, $valore1, $chiave2, $valore2, ...)
In aggiunta, le subroutine hanno nomi che iniziano con Ciascun tipo di variabile ha il proprio spazio dei nomi, così come
parecchi identificativi che non sono relativi a variabili. Ciò significa
che potete, senza temere di creare collisioni, utilizzare lo stesso
identico nome per una variabile scalare, per un array e per una hash e,
per quanto possa contare, per un filehandle, per un handle di
directory, per il nome di una sub, di un formato o anche di
un'etichetta. Ciò implica che A causa del fatto che i nomi delle variabili iniziano sempre
con È possibile rimpiazzare questi nomi alfanumerici con un'espressione che restituisce un riferimento al tipo appropriato. Per una descrizione vedete perlref. I nomi che iniziano con una cifra numerica possono contenere solo
altre cifre numeriche. I nomi che non cominciano con una lettera,
underscore, cifra numerica o con un accento circonflesso (ossia,
un carattere di controllo) sono limitati ad un singolo carattere,
ad esempio
ContestoL'interpretazione di operazioni e valori in Perl a volte dipende dai requisiti del contesto intorno all'operazione o al valore. Ci sono due contesti principali: lista e scalare. Alcune operazioni restituiscono liste in contesti che chiedono liste, e valori scalari altrimenti. Se questo vale per un'operazione, questo fatto sarà menzionato nella relativa documentazione. In altre parole, Perl sovraccarica alcune operazioni basandosi sul fatto che ci si aspetti un valore singolare o plurale. Alcune parole in italiano si comportano allo stesso modo, ad esempio ``pesce'' [che può essere riferito ad una molteplicità - come in ``oggi mangiamo pesce'' - o al singolo elemento - come in ``Ho preso un pesce solo oggi'']. In modo del tutto reciproco, un'operazione fornisce un contesto scalare o lista a ciascuno dei suoi argomenti. Ad esempio, se scrivete
int( <STDIN> )
l'operazione ``intero'' fornisce un contesto scalare all'operatore diamante <>, che dunque reagisce leggendo una singola riga da STDIN restituendola all'operazione ``intero'', che troverà infine il valore intero di quella linea e lo restituirà a sua volta. Se, d'altra parte, scrivete
sort( <STDIN> )
allora l'operazione L'assegnazione è un pochino speciale, nel senso che utilizza il suo argomento a sinistra per determinare il contesto dell'argomento di destra. L'assegnazione ad uno scalare valuta la parte a destra in contesto scalare, mentre l'assegnazione ad un array o ad una hash fa sì che la parte destra sia valutata in contesto lista. Anche l'assegnazione ad una lista (o slice, che è comunque una lista) valutano la parte destra in contesto lista. Quando utilizzate la direttiva Le funzioni definite da utente possono scegliere di comportarsi differentemente se sono chiamate in contesto void, scalare o lista. La maggior parte delle funzioni non avranno però bisogno di preoccuparsene, poiché sia scalari che liste sono automaticamente interpolati in liste. Consultate perlfunc/wantarray per sapere come fare a stabilire dinamicamente in quale contesto è stata chiamata la vostra funzione.
Valori scalariTutti i dati in Perl sono scalari, array di scalari, o hash di scalari. Uno scalare può contenere un singolo valore di tre tipi differenti: un numero, una stringa o un riferimento. In generale, la conversione da una forma all'altra è trasparente all'utente. Sebbene uno scalare non possa contenere valori multipli, può contenere un riferimento ad un array o ad una hash che, a loro volta, possono contenere valori multipli. Gli scalari non devono essere per forza una cosa o l'altra. Non c'è nessun posto dove dichiarare una variabile scalare come ``stringa'', ``numero'', ``riferimento'' o qualsiasi altra cosa. A causa della conversione automatica, le operazini che restituiscono scalari non hanno bisogno di preoccuparsi (ed infatti non lo fanno) se il chiamante sta aspettando una stringa, un numero o un riferimento. Perl è un linguaggio contestualmente polimorfico i cui scalari possono essere stringhe, numeri o riferimenti (il che include gli oggetti). Sebbene stringhe e numeri siano considerati più o meno la stessa cosa per quasi tutti gli scopi, i riferimenti sono puntatori a tipizzazione forte e non modificabili, con un meccanismo di conteggio dei riferimenti [reference-counting, N.d.T.] e chiamata dei distruttori. Un valore scalare è considerato VERO in senso booleano se non è la stringa nulla o il numero 0 (ovvero il suo equivalente stringa ``0''). Il contesto booleano è solo una variante speciale del contesto scalare, dove non viene mai effettuata alcuna conversione verso una stringa o un numero. Ci sono in realtà due varietà di stringhe nulle (a volte
dette stringhe ``vuote''), una definita ed una indefinita. La versione
definita è solo una stringa che ha lunghezza nulla, come Per stabilire se una data stringa è un valore numerico valido e non nullo, è di solito sufficiente confrontarlo sia con lo 0 numerico che con lo ``0'' lessicale (sebbene questo causerà un po' di rumore se gli avvertimenti sono attivati). Ciò segue dal fatto che le stringhe che non sono numeri contano come 0, tale e quale che in awk:
if ($str == 0 && $str ne "0") {
warn "Non sembra essere un numero";
}
Questo metodo potrebbe essere il migliore, perché altrimenti non
considererete notazioni IEEE come
warn "ha caratteri non numerici" if /\D/;
warn "non un numero naturale" unless /^\d+$/; # rifiuta -3
warn "non un numero intero" unless /^-?\d+$/; # rifiuta +3
warn "non an numero intero" unless /^[+-]?\d+$/;
warn "non un numero decimale" unless /^-?\d+\.?\d*$/; # rifiuta .2
warn "non un numero decimale" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
warn "non un float C"
unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
La lunghezza di un array è un valore scalare. Potete trovare la
lunghezza dell'array utilizzando Potete anche guadagnare qualche minuscola frazione di efficienza
allungando un array in anticipo quando sapete che diventerà grande.
Potete estendere un array anche assengando un valore ad un elemento
che si trova fuori dal bordo estremo dell'array. Potete troncare un
array assegandogli la lista nulla
@qualcosa = ();
$#qualcosa = -1;
Se valutate un array in contesto scalare viene restituita la lunghezza dell'array. (Osservate che questo non è vero nel caso delle liste, che restituiscono l'ultimo valore, analogamente all'operatore virgola del C. Non è vero neanche nel caso delle funzioni incorporate, che restituiscono quello che sembra loro più corretto). La seguente affermazione è sempre vera:
scalar(@qualcosa) == $#qualcosa - $[ + 1;
La versione 5 di Perl ha cambiato il significato di
scalar(@qualcosa) == $#qualcosa + 1;
Alcuni programmatori scelgono di utilizzare una conversione esplicita per non lasciare spazio a dubbi:
$numero_di_elementi = scalar(@qualcosa);
Se valutate una hash in contesto scalare viene restituito un
valore FALSO se l'hash è vuota. Se esiste anche una sola coppia
chiave/valore, viene restituito un valore VERO; più precisamente,
il valore restituito è una stringa costituita dal numero di
caselle utilizzate ed il numero di caselle allocate, separate
da una sbarretta obliqua. Questo può essere utile solamente se
volete stabilire se l'algoritmo di hashing interno di Perl si
sta comportando bene o meno sul vostro insieme di dati. Ad
esempio, voi inserite 10.000 elementi in una hash, ma
valutando %HASH in contesto scalare restituisce Potete prenotare spazio per una hash con un'assegnazione alla
funzione
keys(%utenti) = 1000; # alloca 1024 caselle
Costruttori di valori scalariI letterali numerici possono essere specificati in uno qualsiasi dei seguenti formati interi o a virgola mobile:
12345
12345.67
.23E-10 # un numero piuttosto piccolo
3.14_15_92 # un numero molto importante
4_294_967_296 # l'underscore aumenta la leggibilita`
0xff # esadecimale
0xdead_beef # piu` esadecimale
0377 # ottale (solo cifre, inizia con 0)
0b011011 # binario
È consentito utilizzare underscore fra le cifre nei letterali numerici per leggibilità. Potreste, ad esempio, raggruppare le cifre binarie a tre a tre (come nell'impostazione del modo dei file in stile Unix, ad esempio 0b110_100_100), o a quattro a quattro (per rappresentare metà di ottetti, come in 0b1010_0110), o in altri gruppi. Le stringhe letterali sono usualmente delimitate da un apice
singolo o doppio. Entrambi lavorano molto similmente alle virgolette
nelle shell standard Unix: le stringhe letterali con virgolette
doppie sono soggette a sostituzione di backslash e di
variabile; le stringhe con virgolette semplici non lo sono, invece,
(con le uniche eccezioni di Le rappresentazioni esadecimali, ottali o binarie in stringhe letterali
non sono automaticamente convertite alla loro rappresentazione
intera. Le funzioni Potete anche includere a-capo direttamente nelle stringhe, ossia
queste possono terminare in una riga differente da quella in cui
iniziano. Questa è una caratteristica apprezzabile, ma se vi
dimenticate le virgolette di chiusura l'errore non verrà segnalato
finché Perl non trova un'altra riga contenente la virgoletta stessa,
che potrebbe essere molto più in là nello script. La sostituzione di
variabili all'interno delle stringhe è limitato alle variabili
scalari, agli array ed alle
$Prezzo = '$100'; # non interpolato
print "Il prezzo ammonta a $Prezzo.\n"; # interpolato
Non esiste doppia interpolazione in Perl, dunque la parte In alcune shell potete racchiudere il nome della variabile in parentesi graffe per eliminare ambiguità nel caso questo sia seguito da altri caratteri alfanumerici (o underscore). Siete anche obbligati a farlo quando interpolate una variabile all'interno di una stringa per separare il nome della variabile da una successiva coppia di due-punti o da un apostrofo, poiché queste verrebbero altrimenti trattate come separatori di package:
$chi = "Larry";
print PASSWD "${chi}::0:0:Superuser:/:/bin/perl\n";
print "Diciamo ${chi}uccio per vezzeggiare '${chi}'no?.\n";
Senza le parentesi, Perl andrebbe a cercare la variabile Qualunque identificativo in tali parentesi graffe viene forzato
ad essere una stringa, così come qualsiasi identificativo semplice
all'interno di un indice di hash. Nessuno dei due ha bisogno
di virgolette. Nel nostro esempio di prima,
Stringhe di Versione ,Nota: l'uso delle Stringhe di Versione (v-string) è scoraggiato. Non saranno disponibili dopo Perl 5.8, i vantaggi marginali dati dalle v-string erano facilmente messi in secondo piano da un intero potenziale di Sorprese e Confusione. Un letterale della forma
print v9786; # stampa uno smiley codificato UTF-8 "\x{263a}"
print v102.111.111; # stampa "foo"
print 102.111.111; # uguale
Tali letterali sono accettati sia da Da notare che a partire da Perl 5.8.1 le v-string a valore
singolo (come
Letterali SpecialiI letterali __FILE__, __LINE__ e __PACKAGE__ sono speciali e
rappresentano nell'ordine il nome del file sorgente corrente, il
numero di riga ed il nome del package nel particolare punto
del programma in cui vengono utilizzati. Possono essere utilizzati
solo come token separati, non vengono interpolati all'interno
delle stringhe. Se non esiste un package corrente (a causa
della mancanza della direttiva I due caratteri di controllo ^D e ^Z, insieme ai token __END__ e __DATA__, possono essere utilizzati per indicicare la conclusione logica dello script, prima della fine del file in cui è contenuto. Qualunque dato successivo viene ignorato. Il testo successivo a __DATA__ può essere letto utilizzando il
filehandle Consultate SelfLoader per maggiori ragguagli su __DATA__ ed un esempio di utilizzo. Osservate anche che non potete leggere dal filehandle DATA in blocco BEGIN, poiché questo viene eseguito non appena viene incontrato (durante la compilazione), in un punto in cui il corrispondente token __DATA__ (o __END__) non è stato ancora incontrato.
BarewordUna parola che non ha altra interpretazione nella grammatica Perl viene
considerata come se fosse una stringa con virgolette, e viene detta
``bareword'' [parola nuda, N.d.T.]. Come per filehandle ed etichette,
una bareword formata unicamente da lettere minuscole rischia di
entrare in conflitto con possibili parole riservate del linguaggio
che verranno introdotte in futuro; se utilizzate la direttiva
use strict 'subs';
allora qualsiasi bareword tale da NON venire interpretata come una
chiamata a funzione produce un errore di compilazione. Tale restrizione
continua fino alla fine del blocco contenente l'uso della direttiva suddetta;
in più, un blocco più interno può disabilitare tale comando utilizzando
Delimitatore di Unione di ArrayGli array e le slice sono interpolate, all'interno di stringhe racchiuse
da virgolette doppie, unendo gli elementi con il delimitatore specificato
nella variabile
$temp = join($", @ARGV);
system "echo $temp";
system "echo @ARGV";
All'interno dei pattern di ricerca (che seguono le stesse regole di
sostituzione proprie delle virgolette doppie) c'è spazio per una
sfortunata ambiguità: Se state cercando informazioni su come utilizzare here-document, che si trovavano a questo punto di questa pagina del manuale, sappiate che sono state spostate in perlop/Quote and Quote-like Operators [Virgolette ed Operatori Similari, N.d.T.].
Costruttori di Valori di ListaI valori di una lista sono denotati separando i singoli valori utilizzando delle virgole (e racchiudendo la lista fra parentesi, laddove le regole di precedenza lo richiedano):
(LISTA)
In un contesto in cui non viene richiesta una lista di valori, il valore che risulta dalla lista è semplicemente quello dell'elemento finale, proprio come con l'operatore virgola nel linguaggio C. Ad esempio:
@pippo = ('cc', '-E', $pluto);
assegna l'intera lista all'array c<@pippo>, ma d'altra parte:
$pippo = ('cc', '-E', $pluto);
assenga alla variabile scalare
@pippo = ('cc', '-E', $pluto);
$pippo = @pippo; # $pippo viene posta a 3
Potete opzionalmente inserire una virgola prima della parentesi di chiusura di una lista di letterali, ossia potete dire:
@pippo = (
1,
2,
3,
);
Per utilizzare un here-document per assegnare valori agli elementi di un array, una riga per elemento, potreste utilizzare l'approccio che segue.
@salse = <<Fine_Righe =~ m/(\S.*\S)/g;
pomodoro normale
pomodoro condito
chili verde
pesto
vino bianco
Fine_Righe
Le LISTE effettuano automaticamente l'interpolazione sulle sottoliste. In poche parole, quando la LISTA viene valutata, ciascun elemento componente viene valutato in contesto lista, e la lista totale che ne consegue viene intepolata all'interno di LISTA come se quegli elementi individuali fossero membri di LISTA. Per questo motivo, gli array e le hash perdono la propria identità all'interno di una LIST; la semplice lista:
(@pippo, @pluto, &UnaFunzioneQualunque, %boh)
contiene tutti gli elementi di La lista vuota viene rappresentata da (). Interpolarla in una lista non ha effetti. Perciò, ((),(),()) è equivalente a (). In modo simile, interpolare un array senza elementi è identico a pensare che nessun array sia stato mai interpolato fino a questo punto. L'interpolazione va a braccetto con il fatto che le parentesi di
apertura e chiusura sono opzionali (eccezion fatta per quando
tali parentesi sono necessarie per le regole di precedenza) e che le
liste possono essere provviste di una virgola opzionale a
denotare che la presenza di virgole ripetute nella lista costituiscono
una sintassi legale. La lista Un valore di tipo lista può anche essere indicizzato come un array normale; dovete però inserire la lista fra parentesi per evitare ambiguità. Ad esempio:
# La funzione `stat' restituisce un valore lista
$tempo = (stat($file))[8];
# ERRORE DI SINTASSI NELLA RIGA CHE SEGUE
$tempo = stat($file)[8]; # OOPS, HO DIMENTICATO LE PARENTESI
# Trova una cifra esadecimale
$cifra_esadecimale = ('a','b','c','d','e','f')[$cifra-10];
# Un "operatore virgola" al contrario
return (pop(@pippo),pop(@pippo))[0];
Si può effettuare un'assegnazione ad una lista solo quando ciascun elemento della lista è esso stesso un possibile valore legale per il lato sinistro di una assegnazione:
($a, $b, $c) = (1, 2, 3);
($map{'rosso'}, $map{'blu'}, $map{'verde'}) = (0x00f, 0x0f0, 0xf00);
Un'eccezione a questa regola consiste nel fatto che potete assegnare
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
L'assegnazione di una lista in contesto scalare restituisce il numero di elementi prodotti dall'espressione regolare posta alla destra dell'operatore di assegnazione.
$x = (($pippo,$pluto) = (3,2,1)); # imposta $x a 3, non a 2
$x = (($pippo,$pluto) = f()); # imposta $x al conteggio di quanto
# restituito da f()
Ciò è comodo quando volete effettuare un'assegnazione di lista in contesto Booleano, poiché molte funzioni restituiscono la lista nulla in uscita, che una volta assegnata produce 0, il quale a sua volta viene interpretato come falso. Questa proprietà è anche alla base di un utile idioma per eseguire una funzione o per effettuare un'operazione in contesto lista, per poi contare il numero di valori restituiti, assegnando il risultato ad una lista vuota e poi utilizzando l'assegnazione in contesto scalare. Ad esempio, il codice che segue:
$conteggio = () = $testo =~ /\d+/g;
inserisce dentro
$conteggio = $testo =~ /\d+/g;
non funzionerebbe, perché un pattern match in contesto scalare restituisce solo un valore vero o falso, invece che il numero di confronti positivi. L'ultimo elemento di un'assegnazione di lista può essere un array o una hash:
($a, $b, @resto) = split;
my($a, $b, %resto) = @_;
In realtà, potete mettere un array o una hash ovunque nella lista, ma
il primo che viene incontrato farà razzia di tutti i valori, e qualunque
altro elemento successivo assumerà valore Una hash può essere inizializzata utilizzando una lista letterale contenente coppie di elementi che verranno interpretate come chiave e valore:
# stessa assegnazione di map riportata in precedenza
%map = ('rosso',0x00f,'blu',0x0f0,'verde',0xf00);
Mentre potete normalmente scambiare liste letterali e array, ciò non è possibile nel caso delle hash. Solo perché potete indicizzare un valore in una lista come un normale array non vuol dire che possiate indicizzarlo come una hash. In maniera del tutto analoga, le hash incluse all'interno di liste (ivi incluse le liste di parametri e quelle restituite dalle funzioni) sono sempre appiattite in coppie chiave/valore. Questo è un buon motivo per utilizzare i riferimenti, a volte. Spesso risulta più leggibile utilizzare l'operatore
%map = (
rosso => 0x00f,
blu => 0x0f0,
verde => 0xf00,
);
o per iniziare riferimenti ad hash da utilizzare come record:
$rec = {
strega => 'Mabella la Senza Pieta`',
gatto => 'Fuffi il feroce',
data => '10/31/1776',
};
o per impostare parametri con nome per chiamare funzioni complicate:
$campo = $query->radio_group(
name => 'nome_gruppo',
values => ['eenie','meenie','minie'],
default => 'meenie',
linebreak => 'true',
labels => \%labels
);
[Vari elementi sono nome, valori, valore_di_default, a_capo ed etichette. Si è preferito lasciare i nomi originali visto il chiaro riferimento al modulo CGI di Lincoln D. Stein. N.d.T.] Osservate che il fatto che la hash sia inizializzata in questo ordine non significa che gli elementi verranno fuori nello stesso ordine. Consultate perlfunc/sort per avere esempi su come ottenere un'uscita ordinata.
IndicizzazioneUn array viene indicizzato specificando un segno di dollaro (
@mioarray = (5, 50, 500, 5000);
print "L'elemento numero 2 contiene ", $mioarray[2], "\n";
Gli indici di un array iniziano da 0. Un indice negativo va a prendere
il valore corrispondente iniziando dalla fine. Nel nostro esempio,
Le indicizzazioni di una hash sono simili, solo che invece di parentesi quadre occorre utilizzare parentesi graffe. Ad esempio:
%scienziati =
(
"Newton" => "Isaac",
"Einstein" => "Albert",
"Darwin" => "Charles",
"Feynman" => "Richard",
);
print "Il nome di Darwin e' ", $scienziati{"Darwin"}, "\n";
SliceIl metodo più comune di accedere ad un array o ad una hash è un elemento alla volta. Potete indicizzare anche una lista per prendere un singolo elemento.
$chisono = $ENV{"USER"}; # un elemento dalla hash
$antenato = $ISA[0]; # un elemento dall'array
$dir = (getpwnam("daemon"))[7]; # analogo, ma con la lista
Una slice accede a parecchi elementi di una lista, di un array o di una hash contemporaneamente, utilizzando una lista di indici; risulta più conveniente che non scrivere gli elementi singoli come lista di valori scalari separati.
($lui, $lei) = @gente[0, -1]; # slice di array
@loro = @gente[0 .. 3]; # slice di array
($chi, $home) = @ENV{"USER", "HOME"}; # slice di hash
($uid, $dir) = (getpwnam("daemon"))[2, 7] # slice di lista
Poiché potete effettuare assegnazioni a liste di variabili, potete anche effettuarle ad una slice di array o hash:
@giorni[3 .. 5] = qw/ Mer Gio Ven /;
@colori{'rosso', 'blu', 'verde'}
= (0xff0000, 0x0000ff, 0x00ff00);
@gente[0, -1] = @gente[-1, 0];
Queste assegnazioni corrispondono esattamente a
($giorni[3], $giorni[4], $giorni[5]) = qw/ Mer Gio Ven /;
($colori{'rosso'}, $colori{'blu'}, $colori{'verde'})
= (0xff0000, 0x0000ff, 0x00ff00);
($gente[0], $gente[-1]) = ($gente[-1], $gente[0]);
Poiché cambiare una slice cambia l'array o la hash originale dalla quale
proviene, un costrutto
foreach (@array[ 4 .. 10 ]) { s/pietro/paolo/ }
foreach (@hash{qw[ chiave1 chiave2 ]}) {
s/^\s+//; # elimina gli spazi iniziali
s/\s+$//; # elimina gli spazi finali
s/(\w+)/\u\L$1/g; # maiuscole ad inizio di ogni parola
}
Una slice di una lista vuota è ancora una lista vuota. Perciò:
@a = ()[1,0]; # @a non ha elementi
@b = (@a)[0,1]; # @b non ha elementi
@c = (0,1)[2,3]; # @c non ha elementi
Ma:
@a = (1)[1,0]; # @a ha due elementi
@b = (1,undef)[1,0,2]; # @b ha tre elementi
Ciò rende semplice scrivere cicli che si interrompono quando viene restituita una lista nulla:
while ( ($home, $utente) = (getpwent)[7,0]) {
printf "%-8s %s\n", $utente, $home;
}
Come abbiamo osservato in precedenza, l'assegnazione di una lista in contesto scalare restituisce il numero di elementi di quanto si trova alla destra dell'assegnazione. La lista vuota non ha elementi, per cui quando il file delle password è terminato il risultato è 0 invece che 2. Se siete un po' confusi sul perché dovete utilizzare una
Typeglob e FilehandlePerl utilizza un tipo interno detto typeglob per contenere un intero
elemento della tabella dei simboli. Il prefisso di una typeglob è un
carattere L'utilizzo principale delle typeglob nel Perl moderno si ha nella creazione di alias nella tabella dei simboli. Questa assegnazione:
*questo = *quello;
rende
local *Qui::blu = \$Altrove::verde;
rende Un altro utilizzo per i typeglob è per passare filehandle all'interno di funzioni o per creare nuovi filehandle. Se avete bisogno di un typeglob per salvare un filehandle, fatelo così:
$fh = *STDOUT;
o forse meglio con un riferimento reale, come:
$fh = \*STDOUT;
Consultate perlsub per altri esempi di utilizzo di questi riferimenti come filehandle indiretti all'interno delle funzioni. I typeglob sono anche un modo per creare un filehandle locale utilizzando
l'operatore
sub nuova_open {
my $percorso = shift;
local *FH; # non my ma local!
open (FH, $percorso) or return undef;
return *FH;
}
$fh = nuova_open('/etc/passwd');
Ora che abbiamo la notazione Tutte le funzioni che sono in grado di creare filehandle (
sub mia_open {
open my $fh, "@_"
or die "fallita chiamata a open() '@_': $!";
return $fh;
}
{
my $f = mia_open("</etc/motd");
print <$f>;
# $f viene chiusa implicitamente a questo punto
}
Osservate che, se viene usata una variabile scalare inizializzata, il
risultato è differente: Un altro modo per creare un filehandle anonimo si ha utilizzando
il modulo Symbol o con il modulo IO::Handle e la sua genia. Questi
moduli hanno il vantaggio di non nascondere tipi differenti con lo stesso
nome quando si usa
VEDETE ANCHEConsultate perlvar per una descrizione delle variabili predefinite
in Perl e per una discussione sui nomi ammissibili per le variabili.
Vedete perlref, perlsub e perlmod/``Symbol Tables''
[Tabelle dei Simboli, N.d.T.] per maggiori
ragguagli sui typeglob e la sintassi
TRADUZIONE
VersioneLa versione su cui si basa questa traduzione è ottenibile con: perl -MPOD2::IT -e print_pod perldata Per maggiori informazioni sul progetto di traduzione in italiano si veda http://pod2it.sourceforge.net/ .
TraduttoreTraduzione a cura di Flavio Poletti.
RevisoreRevisione a cura di dree. Wed Jan 28 14:17:49 2009 |