Bill Ruppert
Bill Ruppert

Reputation: 9016

Trying to understand Perl sorting the result of a function

I was trying to sort the result of a function, as in sort func(); and got burned because nothing was returned. I guess Perl thought the function call was a sorting routine followed by no data.

Perldoc says the second parameter can be a subroutine name or code block. I see func() as an invocation, not a name. I don't think this is DWIMMY at all.

To further explore how this works, I wrote this:

use strict;
use warnings;

sub func {
    return qw/ c b a /;
}

my @a;

@a = sort func();
print "1. sort func():    @a\n"; 

@a = sort &func;
print "2. sort &func:     @a\n"; 

@a = sort +func();
print "3. sort +func():   @a\n"; 

@a = sort (func());
print "4. sort (func()):  @a\n"; 

@a = sort func;
print "5. sort func:      @a\n"; 

The output, no warnings were generated:

1. sort func():
2. sort &func:     a b c
3. sort +func():   a b c
4. sort (func()):  a b c
5. sort func:      func

Number 1 is the behavior that got me - no output.

I am surprised that 2 works while 1 does not. I thought they were equivalent.

I understand 3 and 4, I used 4 to fix my problem.

I'm really confused by 5, especially given there were no warnings.

Can someone explain what is the difference between 1 & 2, and why 5 outputs the name of the function?

Upvotes: 15

Views: 330

Answers (2)

mob
mob

Reputation: 118605

sort func() parses as sort func (), i.e., sort an empty list [()] with the routine func.

And #5 parses as sort ("func"), sort a list containing the (bareword) string func. Maybe there ought to be a warning about this, but there isn't.


Deparser output:

$ perl -MO=Deparse -e '@a1 = sort func();' -e '@a2=sort &func;' \
    -e '@a3=sort +func();' -e '@a4=sort (func());' -e '@a5=sort func;'
@a1 = (sort func ());
@a2 = sort(&func);
@a3 = sort(func());
@a4 = sort(func());
@a5 = sort('func');
-e syntax OK

Upvotes: 12

Hunter McMillen
Hunter McMillen

Reputation: 61512

There is a section from the perldoc that shows exactly how to sort the return of a function call: http://perldoc.perl.org/functions/sort.html

Warning: syntactical care is required when sorting the list returned from a function. If you want to sort the list returned by the function call find_records(@key) , you can use:

@contact = sort { $a cmp $b } find_records @key;
@contact = sort +find_records(@key);
@contact = sort &find_records(@key);
@contact = sort(find_records(@key));

So in your case you could do:

@a = sort( func() );

Upvotes: 10

Related Questions