Global symbol requires explicit package name adică în limba română: "simbolul global necesită un nume de pachet explicit", este un mesaj de eroare comun, și după opinia mea unul foarte derutant al interpretorului Perl. Cel puțin pentru începători.

Sensul mesajului ar fi "Trebuie să declari o variabilă cu ajutorul operatorului my."

Cel mai simplu exemplu

use strict;
use warnings;

$x = 42;

Iar eroarea este

Global symbol "$x" requires explicit package name at ...

deși mesajul este corect, este puțin folositor programatorului Perl începător. Probabil ei nu au învățat încă ce sunt pachetele (n.t. en: packages). Și nici nu știu ce poate fi mai explicit decât $x ?

Această eroare este generată de use strict.

Explicația din documentație este:

Aceasta generează o eroare la compilare dacă accesezi o variabilă care nu a fost declarată via "our" sau "use vars", localizată via "my()", sau nu a fost calificată variabile (en: fully qualified).

Un începător, este de dorit să înceapă toate scripturile cu use strict, și probabil va învăța despre my mult înainte de celelalte variante.

Nu știu dacă acest mesaj de eroare poate fi, sau ar trebui să fie schimbat în Perl. Nu acesta este scopul acestui articol. Scopul este să ajutăm începătorii să înțeleagă, la nivelul lor, ce înseamnă de fapt acest mesaj de eroare.

Pentru a elimina mesajul de eroare de mai sus trebuie să scriem:

use strict;
use warnings;

my $x = 42;

Adică, trebuie să declarăm variabila folosind "my" înainte de prima utilizare..

Soluția nerecomandată

Cealaltă "soluție" este este să ștergem use strict:

#use strict;
use warnings;

$x = 23;

Aceasta va funcționa, dar acest cod va genera o atenționare: Name "main::x" used only once: possible typo at ....

În orice caz, în mod normal nu v-ați conduce mașina fără centura de siguranță, nu-i așa?

Exemplul 2: scopul

Un alt caz des întâlnit arată cam așa:

use strict;
use warnings;

my $x = 1;

if ($x) {
my $y = 2;
}

print $y;

Mesajul de eroare pe care-l primim este același ca mai sus:

Global symbol "$y" requires explicit package name at ...

Ceea ce este surpinzător pentru multă lume. Mai ales când încep să scrie programe. La urma urmelor au declarat $y folosind my.

Întâi de toate îți sare în ochi o problemă. Indentarea lui my $y = 2; lipsește. Dacă ar fi fost indentat cu câteva spații sau cu un Tab la dreapta, ca în exemplul următor, sursa problemei ar fi fost evidentă:

use strict;
use warnings;

my $x = 1;

if ($x) {
    my $y = 2;
}

print $y;

Problema este că variabila $y este declarată în cadrul blocului, (între perechea de acolade) ceea ce înseamnă că nu există în afara acelui bloc. Aceasta se numește vizibilitatea variabilei (n.t. en: scope).

Conceptul de vizibilitate diferă în funcție de limbajul de programare. În Perl, un bloc închis între acolade creează o vizibilitate limitată. Ceea ce este declarat înăuntru folosind my nu va fi accesibil în afara blocului.

(Apropo $x = 1 este folosit numai pentru a da o aparență de legitimitate care creează o vizibilitate. Cu alte cuvinte, condiționarea if ($x) { este menită pentru a face ca exemplul să arate realist.)

Soluția este, ori să punem print în interiorul blocului:

use strict;
use warnings;

my $x = 1;

if ($x) {
    my $y = 2;
    print $y;
}

ori declarăm variabila în afara blocului (și nu în interior!):

use strict;
use warnings;

my $x = 1;
my $y;

if ($x) {
    $y = 2;
}

print $y;

Care variantă o alegeți depinde de sarcina reală. Acestea sunt doar soluții posibile și corecte d.p.d.v. sintactic.

Bine înțeles, dacă uităm să ștergem my din interiorul blocului, sau dacă $x este fals, atunci primim un mesaj de avertizare Use of uninitialized value (folosirea unei valori neinițializate).

Celelalte căi

Explicațiile privind our și use vars, sau cum se pot califica numele de variabile este subiectul altor articole.