使用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
未设置:
在连接(。)中使用未初始化的值$ IsDryRun2或在TIFFconvert.pl第197行(#1)使用字符串(未初始化)使用未定义的值,就像它已经定义一样。它被解释为“”或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提供。
您需要创建一个子引用,使用所需的参数调用您想要的sub:
find(
sub {
findFiles({ anInIsDryRun2 => $isDryRun });
},
$startDir
);
这或多或少是令人讨厌的。这不是很好。 :)
您可以创建任何类型的代码引用。您不必使用对命名子例程的引用。有关如何执行此操作的许多示例,请参阅我的File::Find::Closures模块。我创建了该模块来准确回答这个问题。
请参阅PerlMonks条目Why I hate File::Find and how I (hope I) fixed it,描述如何使用闭包。
#
# -----------------------------------------------------------------------------
# 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);
}
}