Попытка понять Perl, сортируя результат функции

Я пытался отсортировать результат функции, как в sort func();, и сгорел, потому что ничего не было возвращено. Думаю, Perl считал, что вызов функции - это процедура сортировки, за которой нет данных.

Perldoc говорит, что вторым параметром может быть имя подпрограммы или блок кода. Я вижу func() как вызов, а не имя. Я не думаю, что это DWIMMY вообще.

Чтобы продолжить изучение того, как это работает, я написал следующее:

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"; 

Вывод, никаких предупреждений не было создано:

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

Номер 1 - это поведение, которое меня достало - нет вывода.

Я удивляюсь, что 2 работает, а 1 нет. Я думал, что они эквивалентны.

Я понимаю 3 и 4, я использовал 4, чтобы исправить мою проблему.

Я действительно смущен 5, особенно учитывая, что никаких предупреждений не было.

Может кто-нибудь объяснить, в чем разница между 1 и 2, и почему 5 выводит имя функции?

Ответы

Ответ 1

sort func() анализирует как sort func (), т.е. сортирует пустой список [()] с помощью подпрограммы func.

И # 5 анализирует как sort ("func"), сортирует список, содержащий строку (gwordword) func. Может быть, должно быть предупреждение об этом, но нет.


Выход с помощью Deparser:

$ 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

Ответ 2

Существует раздел из perldoc, который показывает, как сортировать возврат вызова функции: http://perldoc.perl.org/functions/sort.html

Внимание: при сортировке списка, возвращаемого функцией, требуется синтаксическая помощь. Если вы хотите отсортировать список, возвращаемый функцией call find_records (@key), вы можете использовать:

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

Итак, в вашем случае вы можете сделать:

@a = sort( func() );