Global symbol requires explicit package name is a common, and IMHO very misleading error message of Perl. At least for beginners.

The quick translation would be "You need to declare the variable using my."

The simplest example

use strict;
use warnings;

$x = 42;

And the error is

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

While the actual error message is correct, this is little use for the beginner Perl programmer. They have probably not learned what packages are. Nor do they know what can be more explicit than $x ?

This error is generated by use strict.

The explanation in the documentation is:

This generates a compile-time error if you access a variable that wasn't declared via "our" or "use vars", localized via "my()", or wasn't fully qualified.

A beginner will hopefully start every script with use strict, and will probably learn about my long before any of the other possibilities.

I don't know if the actual text can and should be changed in perl. That's not the point of this post. The point is to help beginners understand in their own language what does this error message mean.

To eliminate the above error message one needs to write:

use strict;
use warnings;

my $x = 42;

That is, one needs to declare the variable using my before its first use..

The bad solution

The other "solution" is to remove strict:

#use strict;
use warnings;

$x = 23;

that would work but this code will generate a Name "main::x" used only once: possible typo at ... warning.

In any case, normally you would not drive a car without the safety belt, would you?

Example 2: scope

Another case I often see with beginners looks like this:

use strict;
use warnings;

my $x = 1;

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

print $y;

The error we get is the same as above:

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

which is surprising for many people. Especially when they start their coding. After all they declared $y using my.

First, there is a little visual problem. The indentation of my $y = 2; is missing. If it was indented a few spaces or a tab to the right, as in the next example, the source of the problem might be more obvious:

use strict;
use warnings;

my $x = 1;

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

print $y;

The problem is, that the variable $y is declared within the block, (the pair of curly braces) which means it does not exist outside of that block. This is called the scope of the variable.

The whole idea of scope is different among programming languages. In Perl, a block enclosed in curly braces creates a scope. What is declared inside using my will not be accessible outside the block.

(BTW the $x = 1 is there only to have a legitimate-looking condition that creates the scope. In other words, the if ($x) { condition is there to make the example look real.)

The solution is either to call the print inside the block:

use strict;
use warnings;

my $x = 1;

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

or to declare the variable outside the block (and not inside!):

use strict;
use warnings;

my $x = 1;
my $y;

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

print $y;

Which way you do will depend on the actual task. These are just the syntactically possible correct solutions.

Of course, if we forget to remove the my from inside the block, or if $x is false, then we get a Use of uninitialized value warning.

The other ways

Explaining what our, and use vars do, or how can one fully qualify a variable name is left to another post.