Search code examples
perl

Perl: Why does \@_ provide an alias to the passed in array?


This is a follow up to the question posted here: How do I take a reference to an array slice in Perl?

sub getArrayRef { return \@_ }

my @arr = (0, 1, 2, 3, 4);
my $sub_arr = getArrayRef(@arr[1..2]); # Changes made to $sub_arr->[0] reflect in $arr[1]

I just want to know why this works. The author of the post said it works due to "aliasing magic," but I have no idea what that means.

This method is different from trying to take the reference from the slice:

my @arr = (0, 1, 2, 3, 4);
my $sub_arr = \@arr[1..2]; # array of references rather than aliases to elements of @arr

What's special about @_ that \ makes it return aliases to the variable instead of references?


Solution

  • "Aliasing magic" means that Perl plays several tricks to be as fast as it can. One of those tricks is to alias values instead of copying them. The values in @_ are not copies so Perl doesn't have to move data around for a very common operation that probably happens frequently.

    This is also true in other situations, including the loop variable for foreach:

    use v5.10;
    
    my @items = qw( a b c );
    say "items: @items";
    
    foreach my $item ( @items ) {
        $item = uc($item);
        }
    
    say "items: @items";
    

    By changing the control variable, you actually change the original:

    items: a b c
    items: A B C
    

    To get around this, don't modify the control variables, @_, and some other things that perl gives you. The trick that Eric is using in How do I take a reference to an array slice in Perl? is something you should avoid simply because it will confuse everyone, including future you.