masood91 has asked for the wisdom of the Perl Monks concerning the following question:

I am facing some sifficulties in understanding use of @_ in perl subroutines. @_ is a default array in which arguments passed to a subroutine are stored. Right, then why not use this staement for getting those arguments

my $a=@_ Why we use shift? look at this line of code..
abc(3271); sub abc{ my $a=shift; #what is it? why are we shifting?? }

Replies are listed 'Best First'.
Re: difficulty in understanding use of @_ and shift in a subroutine
by Athanasius (Archbishop) on Oct 27, 2014 at 06:17 UTC

    Hello masood91, and welcome to the Monastery!

    In Perl, arguments are passed into subroutines by reference (as opposed to a language like C, in which arguments are passed by value). The special variable @_ contains aliases to the arguments passed in, so you can use them directly:

    sub abc { $_[0] = 42; }

    but that changes the variables outside of the subroutine. For example, if the above were called as follows:

    my $x = 17; abc($x);

    then after the subroutine call $x would contain 42. Since this is usually not what you want, it is standard practice to simulate pass-by-value by copying the arguments as the first statement in the subroutine:

    sub abc { my ($x, $y, $z) = @_; }

    or (less commonly):

    sub abc { my @args = @_; }

    (Note that @_ is an array variable.) To remove the first element from an array and get its value, Perl provides shift:

    my $num = shift @array;

    After this operation the first element in @array has been removed and stored in the scalar variable $num. Now, within a subroutine, if shift is used without an argument then it automatically applies to @_. Hence, another common idiom is:

    sub abc { my $x = shift; my $y = shift; my $z = shift; }

    which does the same as:

    sub abc { my ($x, $y, $z) = @_; }

    except that with shift the elements are also removed from the @_ array.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: difficulty in understanding use of @_ and shift in a subroutine
by Loops (Curate) on Oct 27, 2014 at 06:13 UTC

    Hi masood91, welcome to the monastery.

    You're free to use whichever form you like to process arguments. There may be efficiency gains one way or the other, but usually that isn't overly important. More often, it just is more clear in the shift form.

    You should be careful though, because your suggestion of using "my $a=@_" wont actually work as you hope. Instead $a will be set to the number of values contained in @_. What you'd want instead is:

    my ($a) = @_;  # force list context in the assignment

    or

    my $a = $_[0];  # set $a to the first parameter passed

    Here's an example where you might prefer to use shift:

    abc('hello', 3271, 33, 44); sub abc{ my $a = shift; print "$a $_\n" for (@_) }
      Right.. Thanks for clearing my confusion. I have been searching this for hours, and at last I remember why not search a Perl forum, if there is any. S here I am. Thanks for your reply and welcoming me. Hope I will learn a lot here. My ultimate goal is web development using Perl. I have started reading "Beginning Perl" book. Suggest me some for web development if you know :) Thanks a lot
        for a quick lesson u could also read man perlsub or perldoc perlsub.
        all the best for your perl journey .it will rock!
        Do not wait to strike when the iron is hot! Make it hot by striking - WB Yeats
Re: difficulty in understanding use of @_ and shift in a subroutine
by johngg (Canon) on Oct 27, 2014 at 10:24 UTC

    Note that while shift operates on @_ by default in a subroutine, in the main body of a script it operates on @ARGV, i.e. arguments supplied on the command line. This one-liner illustrates that.

    $ perl -E 'say $x while $x = shift' aaa bbb ccc aaa bbb ccc $

    I hope this is of interest.

    Cheers,

    JohnGG