Viene spiegato più approfonditamente in perlsyn. In sintesi, non
c'è un'istruzione case ufficiale a causa della varietà di
test che sono possibili in Perl (confronto numerico, confronto tra stringhe,
confronto tra glob, pattern matching, operatori di confronto con più
significati, ...). Larry non è riuscito a decidere quale fosse il
modo migliore per farlo, e quindi lo ha lasciato da parte, benché
sia nella lista dei desideri già dalla prima versione di Perl.
A partire da Perl 5.8 per avere switch e case si deve usare l'estensione
Switch:
use Switch;
e si avranno switch e case. Non è veloce quanto potrebbe esserlo,
poiché non è realmente parte del linguaggio (è fatto
usando i source filter) ma è disponibile, ed è molto
flessibile.
Se però si vuole usare Perl puro, la risposta generale è
scrivere un construtto come questo:
for ( $variabile_da_verificare ) {
if (/pat1/) { } # fai qualcosa
elsif (/pat2/) { } # fai qualcos'altro
elsif (/pat3/) { } # fai qualcos'altro
else { } # default
}
Ecco un semplice esempio di switch basato su pattern matching, questa volta
incolonnato in maniera tale che assomigli maggiormente ad una istruzione
switch. Realizzeremo un costrutto condizionale a più vie basato sul
tipo di riferimento memorizzato in $ref:
SWITCH: for (ref $ref) {
/^$/ && die "non e` un riferimento";
/SCALAR/ && do {
print_scalar($$ref);
last SWITCH;
};
/ARRAY/ && do {
print_array(@$ref);
last SWITCH;
};
/HASH/ && do {
print_hash(%$ref);
last SWITCH;
};
/CODE/ && do {
warn "non posso stampare un riferimento a funzione";
last SWITCH;
};
# DEFAULT
warn "Tipo definito dall'utente, tralasciato";
}
Consultate perlsyn/"Basic BLOCKs and Switch Statements ["BLOCK di Base e Istruzioni Switch", NdT]
per trovare molti altri esempi in questo stile.
A volte potreste dover modificare la posizione della costante e della
variabile. Ad esempio, poniamo che vogliate sapere quale tra tante risposte
avete ricevuto, ma in maniera non dipendete dalle maiuscole/minuscole, e permettendo abbreviazioni.
Potreste usare la seguente tecnica se le stringhe cominciano tutte con
caratteri diversi, o se volete ordinare le corrispondenze in maniera tale che
una abbia la precedenza sull'altra, così come in questo caso SEND
ha la precedenza su STOP:
chomp($answer = <>);
if ("SEND" =~ /^Q$answer/i) { print "L'azione e` send\n" }
elsif ("STOP" =~ /^Q$answer/i) { print "L'azione e` stop\n" }
elsif ("ABORT" =~ /^Q$answer/i) { print "L'azione e` abort\n" }
elsif ("LIST" =~ /^Q$answer/i) { print "L'azione e` list\n" }
elsif ("EDIT" =~ /^Q$answer/i) { print "L'azione e` edit\n" }
Un approccio del tutto differente consiste nel creare un hash di riferimenti
a funzione:
my %commands = (
"felice" => \&gioia,
"triste" => \&grigiore,
"finito" => sub { die "Ci vediamo!" },
"matto" => \&rabbia,
);
print "Come stai? ";
chomp($string = <STDIN>);
if ($commands{$string}) {
$commands{$string}->();
} else {
print "Non esiste questo comando: $string\n";
}
|