Ci sono due tipi principali di variabili in Perl. Uno di essi comprende le variabili globali di package, dichiarate con il costrutto use vars (ora obsoleto) oppure con our.

L'altro comprende le variabili lessicali dichiarate con my.

Vediamo che cosa succede quando dichiarate una variabile usando my. In quali parti del codice è visibile? In altre parole, qual è lo scope della variabile?

Scope di variabili: blocco

#!/usr/bin/perl
use strict;
use warnings;

{
    my $email = 'pippo@pluto.com';
    print "$email\n";     # pippo@pluto.com
}
# print $email;
# $email does not exists
# Global symbol "$email" requires explicit package name at ...

All'interno del blocco anonimo (delimitato dalla coppia di parentesi graffe {}), troviamo anzitutto la dichiarazione di una nuova variabile $email. Questa variabile esiste dal punto in cui è dichiarata fino alla fine del blocco. Per questo la linea dopo la parentesi graffa chiusa } ha dovuto essere commentata. Se rimuoveste il # dalla linea # print $email; e provaste ad eseguire lo script, ricevereste il seguente errore di compilazione: Global symbol "$email" requires explicit package name at ....

In altre parole, lo scope di ogni variabile dichiarata con my è il blocco che la contiene..

Scope di variabili: visibilità globale

La variabile $lname è dichiarata all'inizio del codice. Risulta quindi visibile ovunque fino alla fine del file. Anche all'interno di blocchi. E anche se questi blocchi fanno parte di dichiarazioni di funzioni. Se modifichiamo la variabile all'interno di un blocco, tale cambiamento si riflette nel resto del codice. Anche quando si esce dal blocco:

#!/usr/bin/perl
use strict;
use warnings;

my $lname = "Pippo";
print "$lname\n";        # Pippo

{
    print "$lname\n";    # Pippo
    $lname = "Altro";
    print "$lname\n";    # Altro
}
print "$lname\n";        # Altro

Variabili nascoste da altre dichiarazioni

#!/usr/bin/perl
use strict;
use warnings;

my $fname = "Pippo";
print "$fname\n";        # Pippo

{
    print "$fname\n";    # Pippo

    my $fname  = "Altro";
    print "$fname\n";    # Altro
}
print "$fname\n";        # Pippo

In questo caso la variabile $fname è dichiarata all'inizio del codice. Secondo quanto scritto sopra, essa sarà visibile ovunque fino alla fine del file, eccetto dove è nascosta dalla dichiarazione di una variabile locale con lo stesso nome.

All'interno del blocco abbiamo usato my per dichiarare un'altra variabile con lo stesso nome. In questo modo la variabile $fname dichiarata fuori dal blocco viene nascosta finché non si esce dal blocco stesso. Alla fine del blocco (chiuso da }), la variabile $fname dichiarata nel blocco viene distrutta e la variabile $fname originale diventa di nuovo accessibile. Questo meccanismo è particolarmente importante in quanto rende facile creare delle variabili all'interno di piccoli scope senza doversi preoccupare dei possibili usi degli stessi nomi all'esterno.

Stesso nome in più blocchi

Potete liberamente usare lo stesso nome di variabile in più di un blocco. Tali variabili sono indipendenti le une dalle altre.

#!/usr/bin/perl
use strict;
use warnings;

{
    my $name  = "Pippo";
    print "$name\n";    # Pippo
}
{
    my $name  = "Altro";
    print "$name\n";    # Altro
}

Dichiarazione di package nel file

Questo esempio è un po' più avanzato, ma è importante menzionarlo qui:

Perl permette di spostarsi da un name-space a un altro usando l'istruzione package all'interno di un file. Una dichiarazione di package NON delimita uno scope. Se dichiarate una variabile $fname nel package main implicito, che è semplicemente il corpo del vostro script, tale variabile sarà visibile anche in altri name-space nello stesso file.

Se dichiarate una variabile $lname nel name-space 'Altro', essa sarà ancora visibile quando tornate al name-space main. Se la dichiarazione del package Altro fosse in un altro file, le variabili avrebbero un diverso scope determinato da tale file.

#!/usr/bin/perl
use strict;
use warnings;

my $fname  = "Pippo";
print "$fname\n";    # Pippo

package Altro;
use strict;
use warnings;

print "$fname\n";    # Pippo
my $lname = 'Pluto';
print "$lname\n";    # Pluto


package main;

print "$fname\n";    # Pippo
print "$lname\n";    # Pluto