13

使用File::Find,如何将参数传递给处理每个文件的函数?

我有一个遍历目录的 Perl 脚本,以便将一些 3 通道TIFF文件转换为 JPEG 文件(每个 TIFF 文件 3 个 JPEG 文件)。这可行,但我想将一些参数传递给处理每个文件的函数(缺少使用全局变量)。

这是我尝试传递参数的脚本的相关部分:

use File::Find;

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

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

$isDryRun是一个标量。$startDir是一个字符串,一个目录的完整路径。

$IsDryRun2未设置:

在串联 (.) 或 TIFFconvert.pl 第 197 行 (#1) 的字符串中使用未初始化的值 $IsDryRun2 (W 未初始化) 使用未定义的值,就像它已经定义一样。它被解释为“”或 0,但可能是一个错误。要抑制此警告,请为您的变量分配一个定义的值。

(没有参数的旧调用是find ( \&findFiles, $startDir);:)


测试平台(但生产家庭将是 Linux 机器,Ubuntu 9.1,Perl 5.10,64 位):ActiveState Perl 64 位。视窗XP。来自 perl -v: v5.10.0 built for MSWin32-x64-multi-thread Binary build 1004 [287188] 由 ActiveState 提供

4

4 回答 4

16

您需要创建一个子引用,使用所需的参数调用您想要的子引用:

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

这或多或少是柯里化。它只是不是咖喱。:)

于 2010-01-13T12:52:49.937 回答
3

您可以创建您喜欢的任何类型的代码参考。您不必使用对命名子例程的引用。有关如何执行此操作的许多示例,请参阅我的File::Find::Closures模块。我创建了该模块来准确回答这个问题。

于 2010-02-02T12:01:34.330 回答
3

请参阅PerlMonks条目为什么我讨厌 File::Find 以及我(希望我)如何修复它,描述如何使用闭包来做到这一点。

于 2012-01-08T16:09:12.797 回答
0
#
# -----------------------------------------------------------------------------
# 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);
    }
}
于 2018-03-04T10:16:06.477 回答