Как передать параметры в подпрограмму File :: Find, которая обрабатывает каждый файл? - PullRequest
13 голосов
/ 13 января 2010

Используя File :: Find , как я могу передать параметры в функцию, которая обрабатывает каждый файл?

У меня есть Perl-скрипт, который пересекает каталоги, чтобы преобразовать некоторые 3-канальные TIFF файлы в файлы JPEG (3 файла JPEG на файл TIFF). Это работает, но я хотел бы передать некоторые параметры функции, которая обрабатывает каждый файл (за исключением использования глобальных переменных).

Вот соответствующая часть скрипта, где я попытался передать параметр:

use File::Find;

sub findFiles
{
    my $IsDryRun2 = ${$_[0]}{anInIsDryRun2};
}

find ( { wanted => \&findFiles, anInIsDryRun2 => $isDryRun }, $startDir);

$isDryRun - скаляр. $startDir - это строка, полный путь к каталогу.

$IsDryRun2 не установлено:

Использование неинициализированного значения $ IsDryRun2 в конкатенации (.) Или в строке в TIFFconvert.pl line 197 (# 1) (W не инициализирован) Неопределенное значение использовалось так, как если бы оно уже было определены. Это интерпретировалось как "" или 0, но, возможно, это было ошибкой. Для подавления этого предупреждения назначьте определенное значение вашим переменным.

(старый вызов без параметров был: find ( \&findFiles, $startDir);)


Тестовая платформа (но домашним продуктом будет Linux-машина, Ubuntu 9.1, Perl 5.10, 64 бит): ActiveState Perl 64 бит. Windows XP. От perl -v: v5.10.0, собранный для многопоточной MSWin32-x64-бинарной сборки 1004 [287188], предоставленной ActiveState .

Ответы [ 4 ]

15 голосов
/ 13 января 2010

Вам необходимо создать ссылку на ссылку, которая вызывает желаемую ссылку с нужными параметрами:

find( 
  sub { 
    findFiles({ anInIsDryRun2 => $isDryRun });
  },
  $startDir
);

Это более или менее карри.Это просто не довольно карри.:)

3 голосов
/ 08 января 2012

См. Запись PerlMonks Почему я ненавижу File :: Find и как я (надеюсь) исправил это , описывая, как это сделать с замыканиями.

3 голосов
/ 02 февраля 2010

Вы можете создать любой код ссылки, который вам нравится. Вам не нужно использовать ссылку на именованную подпрограмму. Многие примеры того, как это сделать, см. В моем модуле File :: Find :: Closures . Я создал этот модуль, чтобы ответить именно на этот вопрос.

0 голосов
/ 04 марта 2018
#
# -----------------------------------------------------------------------------
# Read directory recursively and return only the files matching the regex
# for the file extension. Example: Get all the .pl or .pm files:
#     my $arrRefTxtFiles = $objFH->doReadDirGetFilesByExtension ($dir, 'pl|pm')
# -----------------------------------------------------------------------------
sub doReadDirGetFilesByExtension {
     my $self = shift;    # Remove this if you are not calling OO style
     my $dir  = shift;
     my $ext  = shift;

     my @arr_files = ();
     # File::find accepts ONLY single function call, without params, hence:
     find(wrapp_wanted_call(\&filter_file_with_ext, $ext, \@arr_files), $dir);
     return \@arr_files;
}

#
# -----------------------------------------------------------------------------
# Return only the file with the passed extensions
# -----------------------------------------------------------------------------
sub filter_file_with_ext {
    my $ext     = shift;
    my $arr_ref_files = shift;

    my $F = $File::Find::name;

    # Fill into the array behind the array reference any file matching
    # the ext regex.
    push @$arr_ref_files, $F if (-f $F and $F =~ /^.*\.$ext$/);
}

#
# -----------------------------------------------------------------------------
# The wrapper around the wanted function
# -----------------------------------------------------------------------------
sub wrapp_wanted_call {
    my ($function, $param1, $param2) = @_;

    sub {
      $function->($param1, $param2);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...