File :: Find и $ _ во вложенных подпрограммах - PullRequest
3 голосов
/ 02 июня 2010

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

Означает ли это, что я не могу положиться на shift, чтобы надежно присвоить $_? Представьте себе, что коллега реализует функцию wtf и не знает, что она вызывается из подпрограммы File::Find wanted . Я запускаю этот код с 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 
}

Ответы [ 3 ]

4 голосов
/ 02 июня 2010

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

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

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

2 голосов
/ 02 июня 2010
0 голосов
/ 02 июня 2010

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

...