How to create an anonymous array ([]) with 'empty slots'?

use feature qw/ say /;
use strict;
use warnings;

my $aref;

$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';

foreach my $idx ( 0 .. $#{$aref} ) {
    say "Testing $idx.";
    say "\t$idx exists." if exists $aref->[$idx];
    say "\t$idx defined." if defined $aref->[$idx];
}

OUTPUT:
Testing 0.
Testing 1.
Testing 2.
    2 exists.
Testing 3.
    3 exists.
    3 defined.
Testing 4.

We pre-allocated five spots in the anonymous array, @{$aref}. The top index is 4. We are able to find what the top index is the same way we created it; by testing the value of $#{$aref}. We can test for existence. We know everything between 0 and 4 was created. But Perl only reports "exists" for array elements that have specifically had something assigned to them (even if it's undef). Therefore, $aref->[2] is reported to exist, but isn't defined. Just for fun, we assigned '' to $aref->[3] to see a test report defined once. But the short story is that even though the array is pre-extended, we can still test for the difference between an element being initialized with undef, and an element being undef through array pre-extension, by using 'exists'.

I can't say that's documented behavior of exists. So there's no guarantee it wouldn't change someday. But it works on 5.8, 5.10, 5.12, and 5.14.

So, looking for a simple way to find which elements were initialized, which were defined, and which were not, here's an example:

use feature qw/ say /;
use strict;
use warnings;

my $aref;

$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';

my @initialized = grep { exists $aref->[$_] } 0 .. $#{$aref};
my @defined = grep { defined $aref->[$_] } 0 .. $#{$aref};
my @uninitialized = grep { not exists $aref->[$_] } 0 .. $#{$aref};
my @init_undef = grep { exists $aref->[$_] and not defined $aref->[$_] } 0 .. $#{$aref};
say "Top index is $#{$aref}.";
say "These elements are initialized: @initialized.";
say "These elements are not initialized: @uninitialized.";
say "These elements were initialized with 'undef': @init_undef.";
say "These elements are defined: @defined."

That should do:

$a=[];
$#$a=4;

Update (replying to @hexcoder): In one statement:

$#{$a=[]}=4

And in one statement that returns the array:

$a = (map(($_,$#$_=4),[]))[0]

Though, not that I recommend using that construction...