代码之家  ›  专栏  ›  技术社区  ›  Peter Mortensen icecrime

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

  •  13
  • Peter Mortensen icecrime  · 技术社区  · 15 年前

    使用 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 未设置:

    在连接(.)或字符串at中使用未初始化的值$isdryrun2 tiffconvert.pl第197行(1) (w未初始化)使用了未定义的值,就好像它已经 定义。它被解释为“”或0,但可能是一个错误。 若要取消此警告,请为变量指定一个已定义的值。

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


    测试平台(但生产基地将是Linux机器,Ubuntu9.1,Perl5.10,64位):ActiveStatePerl64位。WindowsXP。从Perl - V: v5.10.0为ActiveState提供的mswin32-x64-multi-thread binary build 1004[287188]构建 .

    4 回复  |  直到 7 年前
        1
  •  15
  •   hobbs    15 年前

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

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

    这或多或少是在讨价还价。只是不 漂亮的 咖喱。:)

        2
  •  3
  •   brian d foy    15 年前

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

        3
  •  3
  •   Peter Mortensen icecrime    12 年前
        4
  •  0
  •   Peter Mortensen icecrime    7 年前
    #
    # -----------------------------------------------------------------------------
    # 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);
        }
    }
    
    推荐文章