Variable declaration in Perl

One of the 3 features of use strict which is also called use strict 'vars';
requires that you declare every variable before you use it. Well, sort of.

The trouble

Let's see first an example why is this important.

$l1 = 42;
$ll++;
print "$l1\n";

We assign 42 to a variable. Later we increment it by one, and then print it. Surprisingly the variable still contains 42.

The author might even know that he has to declare the variables using my so maybe the code looks like this:

my $l1 = 42;
$ll++;
print "$l1\n";

but the result is the same.

Now imagine that it is not in a 3 lines long example, but in a 1000 lines long
script that you can find in many established places. You'd have a very hard time noticing that the
auto-increment used the letter l twice, while the first and third rows had
a variable with a letter and a number 1.

use strict

If we add a use strict requirement at the beginning of the file,

use strict;
my $l1 = 42;
$ll++;
print "$l1\n";

we will get the following compile-time error message when we try to run the script:

Global symbol "$ll" requires explicit package name at ... line 6.

Seeing that error message isn't that clear either, at least not for the beginners,
we'll see later where does it come from. In the meantime, if you are interested,
you can read more about the error
global symbol requires explicit package name.

In practical terms it means that you have not declared your variable $ll. Of course
running to your editor and declaring my $ll won't do any good. You'll have to understand
that this is actually a typo and the real variable name is $l1.

We might be still frustrated by the original developer who used a variable name that's
hard to differentiate from a letter, but at least we don't spend hours banging
our head against the wall.

The exceptions

As in any living languages (such as English and French) there are exceptions from the rules. In Perl too.

The variables $a and $b are special variables used in the sort function of Perl
and, for historical reasons, are exempt from the requirement to declare them.
I am not saying having such exceptions is a good thing, but it probably cannot be changed without breaking
all the code written in the past 20+ years.
So I'd strongly recommend never using $a and $b in any code except in connection to sort.

Not even in examples!

You can declare variables using our, use vars, and since 5.10 using state as well.
They have different meaning though.

You can also access variables with their fully qualified name ($Person::name in the next example):

We used the explicit package name in the last example. That's, by-the-way where the error
message (global symbol requires explicit package name)
came from, but in the real world you rarely need that form.
You are way better off always declaring your variables using my, and not
using this "fully qualified" form of the variable.

The danger of the explicit package name

As use strict does not apply to the package variables, you can easily make a typo
as I actually did when I wrote the first version of the example:

examples/fully_qualified_name_with_typo.pl

use 5.010;
use strict;
$Person::name = 'Foo';
say $Perlson::name;

and it printed nothing. No error. No warning. Nothing.

In general relying on fully qualified names can be dangerous. Of course they can be useful in
some places, but we'll talk about that another time.

use warnings

Anyway, this brings me to the importance of the use warnings pragmata. If we used that too,