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

I was led to believe that you could assign the number of arguments being fed into a subroutine as well as the arguments themselves into a) a scalar and b) an array in the following manner:

#!/usr/bin/perl5 -w my $theValue; $theValue = Routine(42); print "$theValue"; sub Routine { my ($argCount,@argValues) = @_; return $_0; # returns 42. # return $argCount; # returns 42 but I would have # thought it would return 1 # (representing the number of # arguments received). # return $argValues[0]; # this doesn't work at all # but I would have thought # it would return 42. }
When I try this, however, it becomes clear to me (I think) that the argument is actually getting assigned to $argCount instead of to $argValues[0] (contrary to what I was led to believe).

Does anyone have any suggestions?

Replies are listed 'Best First'.
RE: ( my ($argCount,@argValues) = @_ ) == Bad Idea?
by dlc (Acolyte) on Feb 11, 2000 at 17:58 UTC

    I think you're confusing the way main gets called in C with the way subroutines get called in perl. In C, the main subroutine gets two parameters: the number of command line options, and the options themselves as a **char. In Perl, everything gets stuffed into @_. You can grab the number of parameters by calling my $numparam = scalar @_;, which will give you the number of elements in the array, and then the elements themselves are available via @_. Just be careful to grab the number of elements before you call shift!

Re: the above
by setantae (Scribe) on Feb 11, 2000 at 00:46 UTC
    The wisdom you have been proffered is wisdom indeed, however, you may understand it better if you call Routine and pass it more than one value;
    ie try Routine(42,87,43) in the script above and I think you will soon see what is going on.
Re: ( my ($argCount
by Anonymous Monk on Feb 10, 2000 at 22:34 UTC
    The problem is that you're putting $argCount and @argValues into a list context by enclosing them in the parentheses from the my(). That means that the first value in @_ is assigned to $argCount and the remaining arguments are assigned to @argValues. The solution to this is to do a two step assignment. You say:
    my(@argValues) = @_; my($argCount) = scalar(@argValues); #or $#argValues + 1
    It's necessary to explicity force @argValues into a scalar context for this to work, because again the parens from my() create a list context.
      ...from which it follows that if you *don't* enclose your my variable in parentheses, you don't have to force scalar context:
      my $argCount = @argValues;
Re: ( my ($argCount
by Anonymous Monk on Feb 12, 2000 at 11:09 UTC
    Thanks for the help guys! It was my interpretation of an example or two in the llama book that led me to believe my incorrect method would work.
Re: ( my ($argCount
by stephen (Priest) on Feb 11, 2000 at 03:31 UTC

    To explicate the wisdom offered above:

    You were lead to believe that you could get the number of arguments and the arguments with the following:

    my ($argCount, @argValues) = @_;

    Unfortunately, you were misled. Someone confused Perl with the way a C main() routine gets its arguments from the command line.

    Perl gets its subroutine arguments passed in the @_ array. So, to get the argument values for your subroutine, do this:

    my (@arguments) = @_;

    To get the number of items in a perl array, call it in a scalar context. So:

    my (@arguments) = @_; my $argument_count = scalar(@arguments);

    No separate $argumentCount variable is needed, since Perl arrays know their own lengths.

    Good luck. We're all counting on you.