In perl, an array is prefixed with an '@'
@_ is a special array. It is the array from which all passed arguments in a perl subroutine are accessible. It makes sense to pass all of the parameters to a subroutine as an array because the number of parameters is not fixed in perl (nor should it be). Why then, even in short subs, do we see things like this:
sub replace_nicknames {
my @names = @_;
foreach (@names) {
s/Jack/John/;
s/Bob/Robert/;
print "$_\n";
}
print "\n";
}
instead of this:
sub replace_nicknames {
foreach (@_){
s/Jack/John/;
s/Bob/Robert/;
print "$_\n";
}
print "\n";
}
The answer is because @_ is not really an array of parameters. It is an array of aliases to parameters. The assignment to a new local variable (or array, whatever) ensures that the caller's copy is unchanged when the subroutine exits.
Try it for yourself:
#!/usr/bin/perl
use strict;
my @names = ('Jack Kennedy', 'John Kennedy', 'Bob Hope', 'Robert Hope');
print "Before any test subroutine calls:\n";
&print_array(@names);
&replace_nicknames_safe(@names);
print "After the safe subroutine call:\n";
&print_array(@names);
&replace_nicknames_unsafe(@names);
print "After the unsafe subroutine call:\n";
@print_array(@names);
sub replace_nicknames_safe {
print "Inside safe subroutine:\n";
my @names = @_;
foreach (@names) {
s/Jack/John/;
s/Bob/Robert/;
}
&print_array(@names);
}
sub replace_nicknames_unsafe {
print "Inside unsafe subroutine:\n";
foreach (@_) {
s/Jack/John;
s/Bob/Robert;
}
&print_array(@_);
}
sub print_array {
my @array = @_;
for(my $i=0; $i<=$#array; $i++) {
print "$array[$i]";
unless($i==$#array) {
print ', ';
} else {
print "\n\n";
}
}
}
This should be the output you get:
Before any test subroutine calls:
Jack Kennedy, John Kennedy, Bob Hope, Robert Hope
Inside safe subroutine:
John Kennedy, John Kennedy, Robert Hope, Robert Hope
After the safe subroutine call:
Jack Kennedy, John Kennedy, Bob Hope, Robert Hope
Inside unsafe subroutine:
John Kennedy, John Kennedy, Robert Hope, Robert Hope
After the unsafe subroutine call:
John Kennedy, John Kennedy, Robert Hope, Robert Hope