-+  Associazione
-+  Documenti
 |-  Modern Perl
 |-  Bibliografia
 |-  Articoli
 |-  Talk
 |-  Perlfunc
 |-  F.A.Q.
 |-  F.A.Q. iclp
-+  Eventi
-+  Community
-+  Blog
-+  Link
Corso di Perl



 


indietro

[12] Che cos'è una chiusura?

Le chiusure sono documentate in perlref.

Chiusura è un termine dell'informatica con un signficato preciso ma difficile da spiegare. Le chiusure sono implementate in Perl come subroutine anonime che conservano un riferimento persistente a variabili lessicali non più visibili. Queste variabili lessicali, magicamente, fanno riferimento alle variabili che erano visibili quando la subroutine è stata definita (deep binding).

Le chiusure hanno senso in qualunque linguaggio di programmazione nel quale il valore di ritorno di una funzione può essere esso stesso una funzione, come in Perl. Notate che alcuni linguaggi mettono a disposizione le funzioni anonime, ma non sono in grado di fornire chiusure effettive: il Python, per esempio [1]. Per ulteriori informazioni sulle chiusure, fate riferimento ad un qualunque libro sulla programmazione funzionale. Scheme è un linguaggio che non solo supporta, ma incoraggia l'uso di chiusure.

Ecco una classica funzione che genera una funzione:

    sub generatore_di_funzione_somma {
        return sub { shift() + shift() };
    }
    $funzione_somma = generatore_di_funzione_somma();
    $somma = $funzione_somma->(4,5);      # $sum ora e` 9.

La chiusura funziona come un template di funzione con dello spazio lasciato libero per la personalizzazione, da riempire in seguito. La subroutine anonima restituita da generatore_di_funzione_somma() non è tecnicamente una chiusura poichè non fa riferimento ad alcuna variabile lessicale non più visibile.

Paragonate il caso precedente alla seguente funzione crea_sommatore(), nella quale la funzione anonima che viene restituita contiene un riferimento ad una variabile lessicale non visibile dalla funzione stessa. Questo riferimento richiede che Perl restituisca un'opportuna chiusura, bloccando quindi per sempre il valore che la variabile lessicale aveva quando la funzione è stata creata.

    sub crea_sommatore {
        my $addendo = shift;
        return sub { shift() + $addendo };
    }
    $f1 = crea_sommatore(20);
    $f2 = crea_sommatore(555);

Ora &$f1($n) è sempre 20 più qualunque $n abbiate passato, mentre &$f2($n) è sempre 555 più il valore passato.

Le chiusure sono usate spesso per scopi meno esoterici. Ad esempio, quando volete passare un po' di codice ad una funzione:

    my $linea;
    timeout( 30, sub { $linea = <STDIN> } );

Se il codice fosse stato passato come stringa, '$linea = <STDIN'>, non ci sarebbe stato alcun modo, per l'ipotetica funzione timeout(), di accedere alla variabile lessicale $line visibile dal chiamante.

[1] NdT: questa nozione a proposito di Python non è più vera. A partire dalla versione 2.2 si possono costruire chiusure con variabili di sola lettura. Non conosco gli interpreti Python successivi. Per approfondimenti:

      http://www.norvig.com/python-lisp.html

vedi in inglese

AUTORE E COPYRIGHT

Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan Torkington. Tutti i diritti riservati.

Questa documentazione è libera; puoi ridistribuirla e/o modificarla secondo gli stessi termini applicati al Perl.

Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di codice in questo file sono rilasciati al pubblico dominio. Potete, e siete incoraggiati a farlo, utilizzare il presente codice o qualunque forma derivata da esso nei vostri programmi per divertimento o per profitto. Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese ma non è obbligatorio.

D:
Progetti e documenti in rilievo
Corso di Perl Progetto pod2it
D:
La ML di Perl.it
mongers@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.
Iscriviti!
D:
Annunci Google