perl中的递归子例程出错

时间:2012-06-13 23:28:38

标签: perl

我是Perl的新手。我正在尝试编写一个Perl脚本,它打印目录中所有文件的内容,并递归执行,直到打印目录/子目录中的所有文件。我正在使用以下子程序。

sub print_files_in_dir {
my $file = shift;
if(-d $file){
 my @files=glob "$file/*";
  foreach my $file (@files){
   if(-d $file){
    print_files_in_dir $file;
   }
   else {
    print_file $file;
   }
 } 
 else {
  print_file $file;
 }
}

其中print_file是sub,用于打印单个文件的内容。我得到这个错误,我尝试用一​​个名为dir1的目录执行此代码,该目录包含另一个名为dir2的目录。

  

无法通过包“dir1 / dir2”找到对象方法“print_files_in_dir”(也许你忘了加载“dir1 / dir2”?)

无法弄清楚为什么会抛出这个错误?

4 个答案:

答案 0 :(得分:6)

正如您所了解的那样,省略参数列表周围的parens可能会给您带来非常奇怪的错误。有些甚至是沉默的。例如,print (4+6)*2打印10! (好吧,它会警告你是否应该按照自己的意愿发出警告,所以它并不是真的沉默,但它也不是致命的。)如果一个人遗漏那些parens,就必须小心。

我写这篇是因为我发现你的glob存在问题;如果路径中包含某些字符,例如空格,它将无法工作。

 glob "$file/*"

应该是

 glob "\Q$file\E/*"

由于我在这里,可以消除一些冗余。你的子崩溃到:

sub print_files_in_dir {
   my $file = shift;
   if (-d $file) {
      print_files_in_dir($_) for glob "\Q$file\E/*";
   } else {
      print_file($file);
   }
}

实际上,您可以使用File::Find::Rule进一步折叠它。

use File::Find::Rule qw( );
print_file($_) for File::Find::Rule->file->in('.');

答案 1 :(得分:4)

你正在运行“间接函数调用”,这是一个令人困惑的OOP功能,可能导致该行:

print_files_in_dir $file;

被解析就像你说的那样,这意味着完全不同和无意的事情:

$file->print_files_in_dir();

在函数调用中使用括号(如此),这不会发生:

print_files_in_dir($file);

同样适用于print_file

答案 2 :(得分:1)

在您调用print_files_in_dir时,编译器没有看到子例程的完整定义,因此它不知道它是什么。根据您使用的语法,最好的猜测是它是一个方法调用。

您可以在定义子例程之前通过预定义来纠正此猜测,例如

sub print_files_in_dir;

sub print_files_in_dir {

  my $file = shift;

  if (-d $file) {

    my @files = glob "$file/*";

    foreach my $file (@files) {

      if (-d $file) {
        print_files_in_dir $file;
      }
      else {
        print_file $file;
      }
    }
  } 
  else {
    print_file $file;
  }
}

答案 3 :(得分:-1)

如果你的动机是递归列出文件,请尝试:

     system("ls -R")