2011-11-26 183 views
0

我正在研究Perl中的遞歸文件查找功能,它應該返回一個文件名數組。但是,當我嘗試打印它們時,會發生什麼,我只是得到0。我究竟做錯了什麼?在Perl中返回數組

use strict; 
use File::Basename; 
use constant debug => 0; 

sub isdir { 
    return (-d $_[0]); 
} 

sub isfile { 
    return (-f $_[0]); 
} 

my $level = 0; 

#my @fns =(); 

sub getfn { 
    my @fns =(); 
    my($file, $path) = @_; 
    my (undef, undef, $ext) = fileparse($file, qr"\.[^.]+$"); 
    $level++; 
    print "-->>getfn($level): $file : $path\n" if debug; 
    print "arg:\t$file\t$path ($ext)\n" if debug; 
    if ($ext eq ".bragi") { 
     open my $FILE, "<", "$path/$file" or die "Failed to open $path/$file: $!"; 
     my @lines = <$FILE>; 
     close $FILE; 
     foreach my $line (@lines) { 
      chomp($line); 
      my $fullpath = "$path/$line"; 
      print "---- $fullpath\n" if debug; 
      if (isfile($fullpath)) { 
       #print "file:\t$fullpath\n"; 
       push(@fns, $fullpath); 
       getfn($line, $path); 
      } 
      elsif (isdir($fullpath)) { 
       #print "DIR:\t$fullpath\n"; 
       opendir my ($dh), $fullpath or 
        die "$fullpath does not exist or is not a directory: $!"; 
       my @files = readdir $dh; 
       closedir $dh; 
       foreach my $f (@files) { 
        getfn($f, "$fullpath"); 
       } 
      } 
     } 
    } 
    print "<<--getfn($level)\n" if debug; 
    $level--; 
    #print @fns; 
    return @fns; 
} 


foreach my $f (<*>) { 
    #print "fn: ".$f."\n"; 
    my (undef, undef, $ext) = fileparse($f, qr"\.[^.]+$"); 
    if ($ext eq ".bragi") { 
    print &getfn($f, $ENV{PWD})."\n"; 
    } 
} 
+1

你看過File :: Find :: Closures?你可能不需要做任何工作,或者通過從中竊取代碼來做很少的工作。 :) –

回答

5

這裏的主要問題是,像這樣的一行:

getfn($line, $path); 

並沒有真正做任何事情。它找到子目錄中的所有文件,但它完全丟棄它們。您需要將其返回值併入您的外線電話​​。

的第二個問題是,這:

print &getfn($f, $ENV{PWD})."\n"; 

強制返回的數組被當作標量,所以它打印數組元素而不是內容的數組元素的。你可能想要這樣的東西:

print "$_\n" foreach getfn($f, $ENV{PWD}); 
+0

'print&getfn($ f,$ ENV {PWD}),「\ n」;'也許。連接將導致標量上下文,逗號將保留列表上下文。很好的接收。 – TLP

+0

是否有任何理由將子程序調用的前面添加了'&?我的理解是,在Perl 5中這很少需要,但也許這是一個我不知道的情況。 –

+0

@davorg:我沒有。我的答案中唯一的'&'是在我正在評論的代碼中,我從這個問題中複製過來的。 (也就是說,如果我正在編寫這個程序,我可能會將'getfn'定義爲'sub getfn($$){...',然後我只在遞歸調用中包含'&',只是爲了繞過關於未檢查原型的警告。) – ruakh

1

當您以遞歸方式調用getfn()時,您從不將返回的數組賦值給任何東西。您的唯一任務是:

my @fns =(); 

位於函數頂部,這就是返回的內容。

+0

我不能打印它,而不是分配它嗎? – tekknolagi

+0

噢,好的......謝謝! – tekknolagi

+0

等待不,我把它推到它 – tekknolagi