views:

391

answers:

3

I am relatively new to Perl and I do not want to use the List::Util max function to find the maximum value of a given array.

When I test the code below, it just returns the first value of the array, not the maximum.

sub max
{
    my @array = shift;
    my $cur = $array[0];
    foreach $i (@array)
    {
        if($i > $cur)
        {
            $cur = $i;
        }
        else
        {
            $cur = $cur;
        }
    }
    return $cur;
   }
+6  A: 

Replace

my @array = shift;

with

my @array = @_;

@_ is the array containing all function arguments. shift only grabs the first function argument and removes it from @_. Change that code and it should work correctly!

rjh
This works, but would you mind explaining it? I thought you pass parameters through the shift keyword..?
lotsofsloths
Updated my post :) Btw, you should also do 'foreach my $i' (or 'for my $i', which means the same thing - for and foreach are interchangeable) to explicitly declare the $i variable in the same way you declare @array and $cur.
rjh
Subroutine parameters are passed in the `@_` array. `shift` removes the first value from the specified array and returns it - calling `shift` with no arguments causes it to act on the `@_` array.
Anon.
Very helpful both of you, thanks.
lotsofsloths
lotsofsloths: so the two common ways of "declaring" arguments are: `my ($an_arg, $another_arg) = @_;` or `my $an_arg = shift; my $another_arg = shift;`
ysth
+2  A: 

Why don't you want to use something that works?

One of the ways to solve problems like this is to debug your data structures. At each step you print the data you have to see if what you expect is actually in there. That can be as simple as:

 print "array is [@array]\n";

Or for complex data structures:

 use Data::Dumper;
 print Dumper( \@array );

In this case, you would have seen that @array has only one element, so there it must be the maximum.

If you want to see how list assignment and subroutine arguments work, check out Learning Perl.

brian d foy
I assume he's trying to practice Perl programming. Haven't we all written our own sort function at some point? :)
rjh
I try not to assume. That's why I ask. :)
brian d foy
+2  A: 

You can write the function as:

#!/usr/bin/perl

use strict; use warnings;

print max(@ARGV);

sub max {
    my $max = shift;
    $max >= $_ or $max = $_ for @_;
    return $max;
}

However, it would be far more efficient to pass it a reference to the array and even more efficient to use List::Util::max.

Sinan Ünür