Sure,
\@letters doesn't change. But when you leave the loop,
@letters has been set back to
r a c e--it looks like it hasn't changed, but it's really just been looped back to where it started.
A few more print()'s would make this clear...
Update: Fixed a typo, plus here's a modified version that makes it clearer what's happening (to me, anyhow):
#!perl -l
use strict;
use warnings;
my $some_word = 'race';
my @letters = split //, $some_word;
my (@array1, @array2);
for (1 .. @letters) {
my @new = @letters;
push (@array1, \@new);
push (@array2, \@letters);
my $myshift = shift @letters;
push(@letters, $myshift);
print "$_ : @letters : $array1[-1] : $array2[-1]"
}
print '';
print "array1 contains:";
foreach my $aref (@array1) {
print "$aref => @$aref";
}
print '';
print "array2 contains:";
foreach my $aref (@array2) {
print "$aref => @$aref";
}
__END__
1 : a c e r : ARRAY(0x8067740) : ARRAY(0x805f380)
2 : c e r a : ARRAY(0x807c91c) : ARRAY(0x805f380)
3 : e r a c : ARRAY(0x807c8c8) : ARRAY(0x805f380)
4 : r a c e : ARRAY(0x807c820) : ARRAY(0x805f380)
array1 contains:
ARRAY(0x8067740) => r a c e
ARRAY(0x807c91c) => a c e r
ARRAY(0x807c8c8) => c e r a
ARRAY(0x807c820) => e r a c
array2 contains:
ARRAY(0x805f380) => r a c e
ARRAY(0x805f380) => r a c e
ARRAY(0x805f380) => r a c e
ARRAY(0x805f380) => r a c e
Update 2: kiat asks: (W)hy doesn't \@letters point to the changed @letters inside the loop? That's just it--it does!