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

I'm working on a project that wants me to use references to pass array elements into a subroutine where it will either add them, or multiply them (user specified). I got it to work perfect without using references but now that I have to use them, it isn't even making it through the interpreter (comiler?).

Take a look and see if you can help me out with some tips and pointers.

use warnings; use strict; my $ref = \@ARGV; if ($ARGV[0] eq "add") { #Checks for add my $rtn = add(@{$ref}); #Calls add subroutine print "The sum is: $rtn"; } elsif ($ARGV[0] eq "multiply") { #Checks for multiply my $rtn = multiply(@{$ref}]); #Calls multiply subroutine print "Their product is: $rtn"; } sub add { #add subroutine my ($sum); $sum=0; foreach $_(@_) { #Loops through the array $sum +=$_; #Adds each array element to the r +est } return \$sum; #Returns the sum value } sub multiply { #multiply subroutine my $product=1; foreach $_(@_) { #Loops through the array $product*=$_; #Multiplys each element to last } return \$product; #Returns the product value }

Replies are listed 'Best First'.
Re: references to subroutines
by dragonchild (Archbishop) on Apr 12, 2008 at 21:37 UTC
    You want a dispatch table.
    my %dispatch = ( add => \&add, multiple => \&multiply, ); my ($action, @args) = @ARGV; if ( exists $dispatch{ $action } ) { my $rv = $dispatch{ $action }->( @args ); print "Result of '$action' is '$rv'\n"; } else { warn "Invalid action '$action'\n"; }

    Also, look in List::Util for better versions of your add and multiply routines.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: references to subroutines
by moritz (Cardinal) on Apr 12, 2008 at 21:47 UTC

    Your question has already been answered, so here are just a few minor nits.

    This might be just an artifact from your example, but this will always give a warning. If the first item of @ARGV is add or multiply, it's not numeric, but it is still passed to the add() and multiply() functions.

    Additionally you return \$sum instead of $sum, but you don't dereference it before printing it.

    Oh, and my $rtn = multiply(@{$ref}]); has spurious ] ;-).

Re: references to subroutines
by apl (Monsignor) on Apr 13, 2008 at 01:06 UTC
Re: references to subroutines
by jethro (Monsignor) on Apr 13, 2008 at 11:11 UTC
    Sounds like school homework, not a project.

    You are not really using references to pass arrays (or did you really mean single array elements?) into the subs. You first create a reference (i.e. $ref) but then you dereference it (i.e. @{$ref}) before giving it to the add or multiply sub.

    What was probably meant was to pass just $ref into the sub and then dereference it there.