2017-02-13 41 views
3

我知道我能做到這一點作爲表達式修改:如何通過一個匿名子查找::文件

#!/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"; 
    } 
} 

但是當時我不知道如何通過參考尋子。也許這是我很想念的東西。

編輯:沒關係,這似乎工作:

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

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

    find($subref,$path);  

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

我不得不把尋子推到了底!男人,我覺得很愚蠢:)

+2

無愚蠢的「,它會發生,這就是問題和你的問題肯定試着先解決你的問題。現在看看[我應該怎麼做,當有人回答我的問題?](http://stackoverflow.com/help/someone-answers) – zdim

+1

您嘗試將命名的子定義放在另一個子內。也許你打算將這個子語言詞彙化(這意味着它只在其他子類中有效,就像用'my'聲明的變量),或者你可能沒注意。但無論如何這是不正確的。問題在於Perl如何在編譯時解析這些子定義,並且這些變量在運行時可用。在詞法變量中使用代碼引用的解決方案會更好。 – simbabque

回答

2

我會分開的子目錄(並重命名爲print()之一,因爲它與內置的名稱衝突!),那麼你可以沿着這些線做些事情(如果我'你要正確地什麼M理解):

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;