File::Find и $_ во вложенных подпрограммах

При выполнении следующего кода печатаются имена всех файлов ниже C:\Test. Почему он не печатает только Hello (n раз, в зависимости от того, сколько файлов обрабатывается)?

Означает ли это, что я не могу полагаться на shift для надежного назначения $_? Представьте, что коллега реализует функцию wtf и не знает, что она вызывается из File::Find требуемой подпрограммы. Я запускаю этот код с Strawberry Perl 5.12.

Изменить: этот код также не работает должным образом:

use strict;
use warnings;

wanted();

sub wanted{
    wtf("Hello");
}

sub wtf {
    shift;
    print; #expecting Hello 
}

Так что я думаю, что я совершенно сбился с пути. Очевидно, это не имеет ничего общего с File::Find, сейчас я ищу новое название для этого вопроса. Вот мой исходный код:

use strict;
use warnings;

use File::Find;

find(\&wanted, "C:\\test");

sub wanted{
    wtf("Hello");
}

sub wtf {
    shift;
    print; #expecting Hello 
}

person zedoo    schedule 02.06.2010    source источник
comment
Попробуйте perldoc -f shift - что заставило вас подумать, что shift присваивается $_?   -  person reinierpost    schedule 02.06.2010
comment
Понятия не имею. Я просто имел в виду эту двухстрочную строку: shift; Распечатать;   -  person zedoo    schedule 02.06.2010


Ответы (3)


print по умолчанию печатает $_, а shift по умолчанию сдвигает @_. Если вы хотите, чтобы аргументы передавались подпрограмме, вы должны использовать @_, а не $_. shift возвращает сдвинутое значение, поэтому вы должны сделать что-то вроде этого:

sub wtf {
    my $_ = shift;
    print;
}

Проблема в том, что для вашей переменной $_ задано имя файла, а для @_ заданы аргументы. документация по CPAN для File::Find объясняет это подробно.

person jasonmp85    schedule 02.06.2010
comment
Ничего страшного. Perl просто сбивает с толку. - person jasonmp85; 02.06.2010

shift не присваивается $_.

person daxim    schedule 02.06.2010
comment
Смотрите мой комментарий к ответу jasonmp85. - person zedoo; 02.06.2010

Кстати, на CPAN есть лучшие замены для File::Find - (например: File::Find::Rules или File::Find::Object). File::Find — это действительно своего рода ископаемое из старых времен, окаменевшее от того, что попало в ядро.

person zby    schedule 02.06.2010