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

Monks:

I have yet another general question. I'm working on debugging a perl program, and have been having to do a lot of reverse-engineering. With my primitive understanding of Perl this has been difficult, but I think I'm almost there. I just need (maybe) one piece of crucial information. Here is the subroutine I'm looking at:

sub SearchPubMed { my $InputRow = shift; # temporary! InputRow = SearchTermID my $QueryID = shift; my $CannedQueriesPurpose = shift; my $CannedQueriesQuery = shift; my $query;

What exactly does it mean to define variables as shift? I understand that the shift operator grabs the first element of an array, and that when "shift" appears next to white space, it is assumed that it is grabbing from the @_ special array variable. I don't totally understand where @_ has come from here and what is stored in it. Can someone shed some light onto the @_ special variable for me? Thanks oodles.

Replies are listed 'Best First'.
Re: shift operator
by GrandFather (Saint) on Jul 23, 2007 at 22:49 UTC

    The Perl special variable @_ is the list of parameters passed to the sub. So:

    hello ('Hello', 'world'); sub hello { my $hi = shift; my $place = shift; print "$hi $place\n"; }

    Prints:

    Hello world

    Although many people would write the sub as:

    sub hello { my ($hi, $place) = @_; print "$hi $place\n"; }

    to use list assignment rather then shifting out multiple arguments. An even more sophisticated technique is to use "named" parameters by assigning to a hash instead of the positional technique just shown:

    hello (hi => 'Hello', place => 'world'); sub hello { my %params = @_; print "$params{hi} $params{place}\n"; }

    Further reading: perlsub, perlop and perlfunc.


    DWIM is Perl's answer to Gödel
Re: shift operator
by saintly (Scribe) on Jul 23, 2007 at 22:40 UTC
    the '@_' list is your list of input parameters. If someone had said:
    SearchPubMed("A","B","C","D");
    Then in SearchPubMed,
    $InputRow = "A"; $QueryID = "B"; # etc...
    It seems a bit squirrely to have to access your input parameters this way, perhaps. Using 'shift' not only accesses the parameter, but it also removes it (meaning that you cannot later say '$firstParam = $_[0]' to get at the original first parameter, a debatable benefit of not using shift). It may be simpler to rewrite several 'shift' lines as a single line:
    my($inputRow,$QueryId,...) = @_;
    That's typically the way most code is written these days, but there's still some rare cases where repeated use of 'shift' makes for more efficient code.
Re: shift operator
by FunkyMonk (Bishop) on Jul 23, 2007 at 22:41 UTC

    In a subroutine @_ is a list of the arguments to the call. For example...

    mysub(1, 2, 3); sub mysub { print "@_\n"; my $x = shift; print "@_\n"; print "$x\n"; } #Outputs: #1 2 3 #2 3 #1

    shift within a subroutine grabs the first argument to the call. So in the example above, 1 will be removed from @_ and assigned to $x.

Re: shift operator
by Zaxo (Archbishop) on Jul 24, 2007 at 06:30 UTC

    shift is a perl operator which may be applied to any variable with the @ sigil. It strips the array's first position and returns that value. In a sub definition, it is used on @_ which is formed from the argument list.

    After Compline,
    Zaxo