Well, you've already got lots of solutions, but here's mine.
I build the spiral, as a 2-d array, from the inside out.
spiral_numbers(5);
sub spiral_numbers
{
my $n = shift;
local $_;
my @nums = 1 .. $n**2;
my @a = ( [ pop @nums ] );
for my $k ( 2 .. $n )
{
if ( $k & 1 ) # odd
{
push @$_, pop @nums
for @a[ reverse 0 .. $k-2 ];
unshift @a, my $r=[];
unshift @$r, pop @nums
for 1 .. $k;
}
else # even
{
unshift @$_, pop @nums
for @a[ 0 .. $k-2 ];
push @a, my $r=[];
push @$r, pop @nums
for 1 .. $k;
}
}
# print it out
local( $\, $, ) = ( "\n", "\t" );
if ( $n & 1 ) # odd
{
print @$_ for @a;
}
else # even
{
print reverse @$_ for reverse @a;
}
}