in reply to Re^2: Passing an array to a subroutine help?!
in thread Passing an array to a subroutine help?!

Thank you again for your replies. My code now looks as follows...and works...

print "\n\nEnter numbers, one number per line.\nEnter a blank line whe +n all values have been entered.\n"; my @values=(); while ($val=<>) { chomp($val); if ($val != "0") { @values=(@values,$val); } elsif ($val eq "0") { print "Please do not enter values of zero.\n"; } elsif ($val eq "") { last; } } my $arraysize=@values; print "\nYou have entered $arraysize values\n\n"; # &minimum(@values); # &maximum(@values); # &maximum(@values,$arraysize); my $min = minimum(@values); my $max = maximum(@values); my $average = average(@values); print "The minimum you have entered is $min\n\n"; print "The maximum you have entered is $max\n\n"; print "The average of the numbers you entered is $average\n\n"; sub maximum { @args = @_; my $max = $args[0]; foreach $i (@args) { if ($i > $max) { $max = $i; } } return $max; } sub minimum { my @things = @_; my $min = $things[0]; foreach my $z (@things) { if ($z < $min) { $min = $z; } } return $min; } sub average { @stuff = @_; my $sum = 0; ($sum+=$_) for @values; my $average = $sum / $arraysize; return $average; }

I'm elated that it works now, but I'm still not quite understanding how part of it works (which is just as important to me as having it work). We were taught in class to call subroutines by the method I have shown above which is commented out. I'm especially confused by this, because for the "Average" subroutine, I figured I would need to pass "@values" as well as "$arraysize" for it to work, but it seems to work without "$arraysize". $arraysize isn't a global variable in the program because I used  my $arraysize, right? So how can the subroutine still work without passing it to that?

I feel like there's some simple concept here that I am just not able to grasp or something, and it's extremely aggravating.

Another question I have now, is if the subroutines return $min $max $average, why do I need those three lines

my $min = minimum(@values); my $max = maximum(@values); my $average = average(@values);
that set those variables to something again? Shouldn't they just work in the print statements after they're returned from the subroutines?

Replies are listed 'Best First'.
Re^4: Passing an array to a subroutine help?!
by chromatic (Archbishop) on Mar 15, 2011 at 21:11 UTC
    We were taught in class to call subroutines by the method I have shown above which is commented out.

    That's a shame; your instructor is doing you and your colleagues a disservice. That syntax has unfortunate side effects.

    $arraysize isn't a global variable in the program because I used my $arraysize, right?

    $arraysize is a lexical variable due to your use of my, but it is visible to the whole program because its lexical scope is the file itself. It's effectively global, even though it's not a package variable.

    Shouldn't they just work in the print statements after they're returned from the subroutines?

    The values returned from the functions (I use these words very carefully) come from lexical variables with smaller scopes—the scope of the functions themselves:

    my $max = maximum(@values); sub maximum { my $max = shift; for my $arg (@_) { $max = $arg if $arg > $max; } return $max; }

    There are two lexical variables named $max in this code. Within the function, all references to $max refer to the innermost variable. If it didn't declare $max as a lexical within the function, all references to $max would refer to the outer (file-scoped) $max. You're correct that you wouldn't have to use return explicitly in that case...

    ... but when you do treat your functions as black boxes which take inputs and return results and do not modify external variables, you tend to end up with better code. You can be certain that your functions do not modify any external variables on which other functions rely, which makes it much easier to write larger and more robust programs.

    If you'd like to learn more details about lexical scoping and functions and ways to write reliable Perl 5 code, my book Modern Perl is available in several electronic versions for free. It might be a good supplement for your class.

Re^4: Passing an array to a subroutine help?!
by Corion (Patriarch) on Mar 15, 2011 at 21:00 UTC

    The variable $min in your main program has nothing to do with the variable $min in the subroutine sub min {...}. Also see Coping With Scoping.