display | more...

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

Log in or register to write something here or to contact authors.