如何将匿名子传递给Find :: File

时间:2017-02-13 21:10:23

标签: perl perl-module

我知道我可以将其作为表达式修饰符:

#!/usr/bin/perl -w
use strict;
use File::Find;

sub file_find{
    my ($path,$filter) = @_;
    find(sub {print $File::Find::name."\n" if /$filter/}, $path);   
}
file_find($newdir,'\.txt');

或不太可读的内容:

find(sub {if(/$filter/){print $File::Find::name."\n"}}, $path);

但如果我想做这样的事情,我该怎么做呢?

sub file_find{
    my ($path,$filter) = @_;

    find(\&print, $path);

    sub print {
        if(/$filter/){ #Variable $filter will not stay shared
            print $File::Find::name."\n";
        }
    }   
}
file_find($newdir,'\.txt')

我得'变量不会保持共享'。我相信我应该把它变成匿名子:

my $print = sub {
    if(/$filter/){
        print $File::Find::name."\n";
    }
}

但后来我不知道如何将引用传递给find子。也许这是我所遗漏的傻事。

编辑:没关系,这似乎有效:

sub file_find{
    my ($path,$filter) = @_;    

    my $subref = sub{
        if(/$filter/){
            print $File::Find::name."\n";
        }
    };

    find($subref,$path);    

}
file_find($newdir,'\.txt');

我不得不将find sub推到底部!男人,我觉得这么愚蠢:))

1 个答案:

答案 0 :(得分:2)

我会将子区分开(并重命名print(),因为它与内置的名称相同!),然后你就可以沿着这些方向做一些事情(如果我理解的话)你想要的正确):

use warnings;
use strict;

use File::Find;

file_find('.', '.txt');

sub file_find{
    my ($path,$filter) = @_;
    my @files = find(sub {my_print($filter)}, $path);
}
sub my_print {
    my $filter = shift;

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

    if($fname =~ /$filter/){
        print "$fname\n";
    }
}

然而,有了这个说法,File::Find::Rule可以使这些事情非常非常容易(特别是处理文件过滤器,因为它本地处理正则表达式):

use warnings;
use strict;

use File::Find::Rule;

my $filter = '*.txt';
my $dir = '.';

my @files = File::Find::Rule->file()
                            ->name($filter)
                            ->in($dir);

print "$_\n" for @files;