-+  Associazione
-+  Documenti
-+  Eventi
-+  Community
-+  Blog
-+  Link

Ottobre 2013

Dom Lun Mar Mer Gio Ven Sab
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Cerca






 

« Link! (12/9/2006) | Home | OpenExp »

L'operatore che non c'è
18.09.06

Di recente, mi sono imbattuto in Enigmatic Perl,un talk tenuto durante YAPC::EU 2006 a Birmingham (rubo un po' il lavoro a larsen segnalandovi la lista dei talk disponibili). L'autore spiega alcuni costrutti piuttosto criptici che si possono trovare in giro (come l'infame select((select($h), $| = 1)[0])), ed uno mi ha colpito in particolare perché mi è stato utile di recente.

Sostanzialmente il mio problema consisteva nel voler forzare un contesto scalare su un'espressione che però andava, inizialmente, valutata in contesto lista.

*** OK, PANIC ***

L'esempio che riporta l'autore dell'articolo è il seguente: supponete di voler contare quante volte ricorre la parola 'ciao' in una stringa qualsiasi; si potrebbe essere tentati di fare:

my $stringa = 'ciao a tutti, ciao a tutti, ciaoooooo';
my $occorrenze = $stringa =~ m/ciao/g;  # ERRORE: NON CONTA PROPRIO NIENTE!

Ahinoi, il risultato in occorrenze è 1 invece di 3, semplicemente perché il match viene effettuato direttamente in contesto scalare, nel qual caso dà un semplice risultato vero o falso.

La soluzione più elegante (e forse meno leggibile :) individuata è questa:

my $stringa = 'ciao a tutti, ciao a tutti, ciaoooooo';
my $occorrenze =()= $stringa =~ m/ciao/g;

utilizzando cioè =()=, l'operatore che non c'è. Non si tratta, infatti, di un operatore dalla forma bizzarra, ma di una doppia assegnazione, la prima (a destra) dal match ad una lista (rappresentata dalle due parentesi), la seconda dalla lista allo scalare, che è in effetti ciò che ci interessa per "contare" il numero di occorrenze.

Nel mio caso, è stato utile per avere questo tipo di conteggio da una funzione sensibile al contesto di chiamata, come ad esempio quella che segue:

sub sensibile {
   my @retval = qw( ciao a tutti );
   return @retval if wantarray;
   return \@retval;
}

Questa funzione, come si può vedere, restituisce una lista quando chiamata in contesto lista (ossia, quando wantarray è "vera"), altrimenti restituisce un riferimento all'array con i risultati. Per avere il conteggio degli elementi restituiti, quindi, non si può scrivere:

my $conteggio_errato = sensibile(); # ERRORE: OTTENGO UN RIFERIMENTO!

perché altrimenti otterrei come risultato un riferimento ad un array! Con l'operatore che non c'è, invece, risolvo il mio piccolo problema di conteggio:

my $conteggio_corretto =()= sensibile();

Dove ho trovato una funzione del genere? In Mail::IMAPClient, funzione unseen! Il che porta all'inevitabile domanda: "ma non facevi prima ad utilizzare la funzione unseen_count?!?" - ehr...

Inviato da polettix il 18.09.06 18:18
Ti è piaciuto questo articolo? Iscriviti al feed!










Devo ricordare i dati personali?






D:
Sull'autore...
D:
La ML di Perl.it
Iscriviti! mongers@lists.perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
D:
Annunci Google