如何将参数传递给处理每个文件的 File::Find 子例程?

发布于 2024-08-17 12:42:40 字数 1140 浏览 5 评论 0原文

使用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) (W uninitialized) 使用未定义的值,就好像它已经存在一样 定义的。它被解释为“”或 0,但也许这是一个错误。 要抑制此警告,请为您的变量分配一个定义的值。

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


测试平台(但生产环境将是 Linux 机器,Ubuntu 9.1,Perl 5.10,64 位): ActiveState Perl 64 位。 Windows XP。来自 perl -v:为 ActiveState 提供的 MSWin32-x64-多线程二进制版本 1004 [287188] 构建的 v5.10.0

Using File::Find, how can I pass parameters to the function that processes each file?

I have a Perl script that traverses directories in order to convert some 3-channel TIFF files to JPEG files (3 JPEG files per TIFF file). This works, but I would like to pass some parameters to the function that processes each file (short of using global variables).

Here is the relevant part of the script where I have tried to pass the parameter:

use File::Find;

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

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

$isDryRun is a scalar. $startDir is a string, full path to a directory.

$IsDryRun2 is not set:

Use of uninitialized value $IsDryRun2 in concatenation (.) or string at
TIFFconvert.pl line 197 (#1)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.

(The old call without parameters was: find ( \&findFiles, $startDir); )


Test platform (but the production home will be a Linux machine, Ubuntu 9.1, Perl 5.10, 64 bit): ActiveState Perl 64 bit. Windows XP. From perl -v: v5.10.0 built for MSWin32-x64-multi-thread Binary build 1004 [287188] provided by ActiveState.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

随心而道 2024-08-24 12:42:40

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

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

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

You need to create a sub reference that calls your wanted sub with the desired parameters:

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

This is, more-or-less, currying. It's just not pretty currying. :)

简单 2024-08-24 12:42:40

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

You can create any sort of code reference you like. You don't have to use a reference to a named subroutine. For many examples of how to do this, see my File::Find::Closures module. I created that module to answer precisely this question.

熊抱啵儿 2024-08-24 12:42:40

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

See the PerlMonks entry Why I hate File::Find and how I (hope I) fixed it describing how to do it with closures.

情痴 2024-08-24 12:42:40
#
# -----------------------------------------------------------------------------
# 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);
    }
}
#
# -----------------------------------------------------------------------------
# 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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文