2011-11-26 180 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